Форум программистов, компьютерный форум CyberForum.ru

Указатели - C++

Восстановить пароль Регистрация
 
 
Рейтинг: Рейтинг темы: голосов - 27, средняя оценка - 4.63
Hagrael
БТР - мой друг
 Аватар для Hagrael
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
23.06.2011, 20:08     Указатели #1
1) Указатель можно инициализирвоать только с помощью операции *p=&a? А как записать адрес переменной в простую переменную (я пытался это делать через операцию b=&a, но компилятор ругается, говорит, что операция &a возвращает указатель.
2) Почему имеет значение тип указателя? Ведь это просто ссылка на переменную.

И еще один вопрос, не касающийся указателей:
3) Как программа узнает, какие места ОЗУ ей можно занимать (не заняты др. программой), а какие - нет.
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
talis
 Аватар для talis
789 / 541 / 37
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
25.06.2011, 17:14     Указатели #41
А какой вид имеет виртуальная память? Шестнадцатеричное число? И может ли быть у разных программ переменные с одинаковым виртуальным адресом?
Да, могут. Реально это будут разные физические адреса, а виртуальное адресное пространство у каждого процесса своё. Почувствуйте термин - адресное пространство. Виртуальная память - это куча байт, с точки зрения программы идущих друг за другом. В физической памяти это пространство может разрываться, но операционка обеспечивает непрерывность виртуального адресного пространства с точки зрения программы.

Размер может быть не известен, но адрес-то должен... Или нет?
Нет. Когда вы говорите
C++
1
char *str_ptr = new char[16];
вы говорите операционке: "сделай мне где-нибудь 16 байт памяти, лежащих в моём виртуальном адресном пространстве друг за другом, и помести адрес на начало этого массива в переменную str_ptr.

Добавлено через 3 минуты
Цитата Сообщение от Hagrael Посмотреть сообщение
А где хранятся связки Вирт. адрес => Физ. адрес? В .tmp файле?
И может ли ОС выделить одной программе более 4 ГБ памяти? И зачем ОС такие колосальные объемы - 2 ГБ? И точно ли в Windows под начало выполнения программы выделяется 4 ГБ памяти? Может ли быть выделено меньше? А то у меня столько процессов, не верится, что на каждый уходит по 4 ГБ.
Таблица сопоставления адресов (так, кажется) находится в памяти ядра операционки. Не знаю на счёт винды, но unix'ы должны выделять одной программе более 4 гигов памяти. При начале выполнения программы ей выделяется меньше памяти, но страницы реальной памяти пришиваются к её виртуальной по мере необходимости. Ну и освобождаются, соответственно.

Добавлено через 1 час 10 минут
Цитата Сообщение от Hagrael Посмотреть сообщение
Виртуальная память - 16-ричное число, которое и содержится в указателе;
Нет, виртуальная память - это огромная последовательность байт, которые доступны программе для хранения в ней каких-либо значений. Программа втыкает эти значения в разные места виртуальной памяти. Указатель - это число, которое показывает, в каком месте виртуальной памяти находится начало объекта (переменной, структуры, массива...).

Виртуальная память с точки зрения программы непрерывна, а с точки зрения операционки, она фрагментирована, и фрагменты лежат в разных местах физической памяти, может даже не по порядку или даже в свопе. Операционка делает так, чтобы (1) программа не задумывалась о том, где реально находится её память и как к ней подобраться и (2) чтобы две программы сидели каждая в своём виртуальном адресном пространстве и не портили друг другу данные.

Добавлено через 18 секунд
Извините, не сразу заметил апдейт
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
xAtom
 Аватар для xAtom
910 / 735 / 60
Регистрация: 09.12.2010
Сообщений: 1,346
Записей в блоге: 1
25.06.2011, 18:15     Указатели #42
В Windows 32 - разрядных виртуалка начинается 64-kb со свободного блока с нулевым адресом, выгружаемый пул ядра от 0xE1000000 до 0xECFFFFFF = 192mb для хранения динамических структур компонентов ядра. Все пользовательские процессы загружаться в нижнюю часть 2gb-виртуальной памяти а системные верхнию часть dll/sys - драйверы устройств только в верхней области виртуальной памяти доступен весь блок памяти процессов 4gb, все системные модули такие как gdi32, kernel32, user32 и т.п, работают для всех пользовательских процессов в одном экземпляре, также можно создать общий модуль для всех процессов.
Chelioss
179 / 179 / 4
Регистрация: 08.01.2011
Сообщений: 1,131
25.06.2011, 18:44     Указатели #43
Допустим есть две запущенные программы. Для каждой система выделила виртуальную память.
Адрес начала этой виртуальной памяти 0x00000000?
А теперь представим, что эти две программы одинаковые. Тогда будут ли виртуальные адреса переменных совпадать? Если да, то почему эта программа выводит разные адреса, если ее несколько раз запустить? :
C++
1
2
3
4
5
6
7
8
9
10
11
#include <iostream>
using namespace std;
 
int main(void)
{
    int a = 5;
    int *p = &a;
    cout << p;
    cin.get();
    return 0;
}
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
25.06.2011, 18:59     Указатели #44
Chelioss, потому как КАЖДАЯ запущенная программа - это отдельеный процесс, для которого создается отдельный дескриптор и свои таблицы страниц виртуальной памяти. Каждый отдельный процесс имеет собственную виртуальную память и соотеветстсенно, никак не пересекающуюся с другими процессами реальную. Реальная тоже может совпадать, так как страницы могут распределяться таким образом.
Далее, каждый процесс еще и СОБСТВЕННЫЙ стек имеет. А все локальные переменные - они в стеке...
Это не зависит, одна и та же прога запускалась или разные.
Hagrael
БТР - мой друг
 Аватар для Hagrael
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
25.06.2011, 20:21  [ТС]     Указатели #45
talis, спасибо за объяснение.

Но вопросы еще остались. Ядро ОС - это ОЗУ, как я понимаю?

А почему такой код:
C++
1
2
3
4
5
6
7
8
9
#include <iostream>
using namespace std;
 
int main() {
    int a=5, b;
    cout << &a;
    cin >> b;
    return 0;
}
выдает 0x22ff54? Это же 10577524-ый байт! Куда ушла остальная память? На функции?

Мне еще не до конца понятно, почему здесь все говорят, что операция &a возвращает адрес переменной, а не указатель. Но ведь (повторюсь) возвращаемое значение имеет тип type* - тип указателя, а следовательно, это не адрес (простое число), а указатель!

Не могли бы вы сказать, отличаются ли следующие явные приведения типов технически:
C++
1
2
3
b=static_cast<int>(a);
b=int(a);
b=(int) a;
Почему 2-ой вариант является инициализацией? (ну, все операции по сути являются как инициализацией, так и приведением типов)

И хотелось бы узнать, конструкции, подобные static_cast<type_to>(variable) обрабатываются по ходу программы или на уровне компилятора? В смысле, может ли пользователь создавать подобные конструкции? (с угловыми скобками etc). int во 2-ом случае вызывается как функция или это обрабатывается компилятором по-особому? И 3-ий вариант тоже весьма интересен. Почему нельзя записать просто b=int a?

Заранее благодарю за ответы.

Добавлено через 2 минуты
Цитата Сообщение от ValeryLaptev Посмотреть сообщение
КАЖДАЯ запущенная программа - это отдельеный процесс, для которого создается отдельный дескриптор и свои таблицы страниц виртуальной памяти
Отдельные-то они отдельные, но в "продуктовом" файле под переменную всегда выделяется одно и то же место в виртуальной памяти. (или нет?) У меня, к примеру, всегда высвечивается один и тот же адрес переменной.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
25.06.2011, 20:54     Указатели #46
Цитата Сообщение от Hagrael Посмотреть сообщение
Но вопросы еще остались. Ядро ОС - это ОЗУ, как я понимаю?
почитай Таненбаума "Современные операционные системы" ну или как то так название и все вопросы отпадут. А то вопросы и выводы у тебя мягко говоря странные, например как это
Цитата Сообщение от Hagrael Посмотреть сообщение
Но ведь (повторюсь) возвращаемое значение имеет тип type* - тип указателя, а следовательно, это не адрес (простое число), а указатель!
по пути ещё ассемблер освой, непонимание основ подводит тебя и из-за этого ты какую то фигню размусолил аж на пять страниц
Hagrael
БТР - мой друг
 Аватар для Hagrael
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
25.06.2011, 20:57  [ТС]     Указатели #47
pito211, позже я доберусь и до ассемблера, однако пока хочется узнать механизмы.
pito211
 Аватар для pito211
186 / 173 / 8
Регистрация: 22.03.2010
Сообщений: 612
25.06.2011, 21:11     Указатели #48
да уже сто раз тут все механизмы обсудили, указатели разжевали как только могли, а ты до сих пор задаёшь одни и те же вопросы. Про виртуальную память всё подробно расписано в книге, которую я привёл выше. Может лучше её открыть, а не дёргать других людей по пустякам, уж наверно у них есть дела поважнее, чем цитирование литературы, находящейся в свободном доступе? Накрайняк можно в педивикию заглянуть

Добавлено через 4 минуты
Цитата Сообщение от pito211 Посмотреть сообщение
да уже сто раз тут все механизмы обсудили, указатели разжевали как только могли
и если ты не понял чего то про указатели, то это целиком из-за пробелов в знаниях. Значит тут два варианта - заполнить пробелы или оставить как есть

Добавлено через 1 минуту
Цитата Сообщение от Hagrael Посмотреть сообщение
3) Как программа узнает, какие места ОЗУ ей можно занимать (не заняты др. программой), а какие - нет.
на этот вопрос в книге таненбаума целая глава есть ВАП
Hagrael
БТР - мой друг
 Аватар для Hagrael
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
25.06.2011, 21:14  [ТС]     Указатели #49
pito211, в моей книге этих нюансов не описывается, а главу "Указатели" я полностью прошел. Я не заставляю никого помогать и не испытываю злобу на людей этого форума, которые мне не помогают Но будьте добры, не заводите впредь эту тему, если конкретную литературу вы не посоветуете. А эта тема действительно будет полезна не только мне, но и другим новичкам, ведь здесь все изложено кратко.
ValeryLaptev
Эксперт C++
1005 / 784 / 46
Регистрация: 30.04.2011
Сообщений: 1,595
25.06.2011, 21:23     Указатели #50
Hagrael, немного про адреса и указатели.
Память - это массив байтов. А элементы массива, как ты знаешь, ПРОНУМЕРОВАНЫ. От 0 до n-1.
В 32-битной машине этот массив имеет размер 2^32 = 4 гб.
Номер элемента памяти - это и есть адрес. Это положительное целое число. Указатель - это переменная, которая хранит этот номер-адрес. В С++ принято, что при выводе на экран значение указателя (целое число-номер элемента памяти) выводится в шестнадцатеричной системе.
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2011, 10:30     Указатели #51
Цитата Сообщение от talis Посмотреть сообщение
Ответить можно и так, и так. Один и тот же указатель может хранить адрес любого по размеру куска памяти. Потому, что единственное, что он хранит - это адрес начала этого куска.
С этим связана одна проблема:
C++
1
delee [] p;//Сколько байт здесь освобождать?
. Как решается?

Добавлено через 13 минут
Цитата Сообщение от Hagrael Посмотреть сообщение
Каждая программа думает, что она одна. Обеспечивает эту сладкую иллюзию для эгоистки-программы операционная система. Но мне не до конца понятно вот что: в коде откомпилированного файла не хранится точный адрес переменной, по которому ее надо записать. Ведь если так будет, то по этому адресу может находиться другая переменная, и возникнет конфликт.
Не будет никакого конфликта, так как по данному адресу в локальном виртуальном адресном пространстве (именно так, виртуальная память - это вообще файл на винчестере, ни какого отношения он сюда не имеет, а работает с ним единственная программа - операционная система, так что в нём как раз только физические адреса) нет других программ, чьи данные и код могли оказаться по указанному адресу. Я уже писал про отсебячьи карты, так вот, это карты разных райнонов, у каждой проги свой.
Hagrael
БТР - мой друг
 Аватар для Hagrael
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
26.06.2011, 10:34  [ТС]     Указатели #52
Странная вещь у меня тут возникла. Вот код:
C++
1
2
const int a=5;
const int b=a;
Без слова const перед int b код не хочет работать. Т. е. из константы в обычную переменную переводить нельзя. Однако этот код:
C++
1
2
int a[10];
int* b=a;
работает! В чем дело?
taras atavin
Ушёл с форума.
 Аватар для taras atavin
3569 / 1752 / 91
Регистрация: 24.11.2009
Сообщений: 27,619
26.06.2011, 10:35     Указатели #53
Цитата Сообщение от Hagrael Посмотреть сообщение
На этапе компиляции переменные являются указателями?
Нет. Но поля элементов таблицы - указатели.
Hagrael
БТР - мой друг
 Аватар для Hagrael
331 / 273 / 2
Регистрация: 07.01.2010
Сообщений: 1,932
26.06.2011, 10:36  [ТС]     Указатели #54
Непонятно вообще, зачем массив делают константой.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.06.2011, 11:38     Указатели
Еще ссылки по теме:

C++ Написать программу сортировки через указатели на указатели
Указатели и массивы. Указатели и функции C++
Указатели на массивы. Указатели и функции C++

Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Bers
Заблокирован
26.06.2011, 11:38     Указатели #55
Цитата Сообщение от taras atavin Посмотреть сообщение
С этим связана одна проблема:
C++
1
delee [] p;//Сколько байт здесь освобождать?
. Как решается?
Существует небольшая проблема:
int m[]; int * p = m; // or int * p = &m[0];
В рантайме невозможно в принципе узнать, какой тег следует приписать указателю - массив или нет.

Однако, есть безопасная функция, которая позволяет узнать сколько было заявлено при new [количество] ???

И да, кстати:

int* iPtr = new int [10];
delete [] iPtr;

Как вы видите, при удалении данных не нужно указывать явное количество.
Напрашивается вывод: реализация delete[] знает точное количество элементов.
Внимание вопрос: если нечто знает количество элементов, на кой чорт это количество дополнительно помнить?

Вопрос номер два: как узнать, какое количество элементов было выделено с помощью new[]
Варианты с шаманством над адресами не предлагать. Существует безопасная функция.

Вопрос номер три: как узнать, на какое количество элементов вообще ссылается указатель iPtr ?
У кого и как об этом можно спросить?

Главный вопрос номер четыре: Как научить клиентский код различать указатель на объект от указателя на массив?

Добавлено через 36 минут
Цитата Сообщение от Hagrael Посмотреть сообщение
Непонятно вообще, зачем массив делают константой.
см. идеологию "строгой типизации". А так же "почему истовый профессионал сыплет константами везде, где только можно".


/ps константность иногда убивает инкапсуляцию.
Yandex
Объявления
26.06.2011, 11:38     Указатели
Ответ Создать тему
Опции темы

Текущее время: 17:21. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru