Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
 
Рейтинг 4.59/27: Рейтинг темы: голосов - 27, средняя оценка - 4.59
БТР - мой друг
333 / 277 / 47
Регистрация: 07.01.2010
Сообщений: 1,932
1

Указатели

23.06.2011, 20:08. Показов 5473. Ответов 54
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
1) Указатель можно инициализирвоать только с помощью операции *p=&a? А как записать адрес переменной в простую переменную (я пытался это делать через операцию b=&a, но компилятор ругается, говорит, что операция &a возвращает указатель.
2) Почему имеет значение тип указателя? Ведь это просто ссылка на переменную.

И еще один вопрос, не касающийся указателей:
3) Как программа узнает, какие места ОЗУ ей можно занимать (не заняты др. программой), а какие - нет.
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
23.06.2011, 20:08
Ответы с готовыми решениями:

Указатели и указатели на указатели, а также типы данных
Недавно начал изучать Си, перешел с Delphi. Много непонятного и пока процесс идет медленно....

Через указатели на указатели посчитать сумму двух чисел и записать в третье
1. Через указатели на указатели посчитать сумму двух чисел и записать в третье. 2. Написать...

Почему Лафоре использует указатели на указатели, вместо обмена значениями указателей?
Доброго времени суток! Задался теоретическим вопросом. Читал пример из книги Лафоре...

Используя нетипизированные указатели и указатели на подпрограммы обобщить сортировку пузырьком
Смысл задания в том, что нужно отсортировать массив структур из 3х полей по сумме координат есть...

54
794 / 546 / 61
Регистрация: 11.05.2010
Сообщений: 1,298
Записей в блоге: 1
25.06.2011, 17:14 41
Author24 — интернет-сервис помощи студентам
А какой вид имеет виртуальная память? Шестнадцатеричное число? И может ли быть у разных программ переменные с одинаковым виртуальным адресом?
Да, могут. Реально это будут разные физические адреса, а виртуальное адресное пространство у каждого процесса своё. Почувствуйте термин - адресное пространство. Виртуальная память - это куча байт, с точки зрения программы идущих друг за другом. В физической памяти это пространство может разрываться, но операционка обеспечивает непрерывность виртуального адресного пространства с точки зрения программы.

Размер может быть не известен, но адрес-то должен... Или нет?
Нет. Когда вы говорите
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 секунд
Извините, не сразу заметил апдейт
1
935 / 760 / 299
Регистрация: 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 и т.п, работают для всех пользовательских процессов в одном экземпляре, также можно создать общий модуль для всех процессов.
1
186 / 186 / 21
Регистрация: 08.01.2011
Сообщений: 1,139
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;
}
1
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
25.06.2011, 18:59 44
Chelioss, потому как КАЖДАЯ запущенная программа - это отдельеный процесс, для которого создается отдельный дескриптор и свои таблицы страниц виртуальной памяти. Каждый отдельный процесс имеет собственную виртуальную память и соотеветстсенно, никак не пересекающуюся с другими процессами реальную. Реальная тоже может совпадать, так как страницы могут распределяться таким образом.
Далее, каждый процесс еще и СОБСТВЕННЫЙ стек имеет. А все локальные переменные - они в стеке...
Это не зависит, одна и та же прога запускалась или разные.
2
БТР - мой друг
333 / 277 / 47
Регистрация: 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 Посмотреть сообщение
КАЖДАЯ запущенная программа - это отдельеный процесс, для которого создается отдельный дескриптор и свои таблицы страниц виртуальной памяти
Отдельные-то они отдельные, но в "продуктовом" файле под переменную всегда выделяется одно и то же место в виртуальной памяти. (или нет?) У меня, к примеру, всегда высвечивается один и тот же адрес переменной.
0
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
25.06.2011, 20:54 46
Цитата Сообщение от Hagrael Посмотреть сообщение
Но вопросы еще остались. Ядро ОС - это ОЗУ, как я понимаю?
почитай Таненбаума "Современные операционные системы" ну или как то так название и все вопросы отпадут. А то вопросы и выводы у тебя мягко говоря странные, например как это
Цитата Сообщение от Hagrael Посмотреть сообщение
Но ведь (повторюсь) возвращаемое значение имеет тип type* - тип указателя, а следовательно, это не адрес (простое число), а указатель!
по пути ещё ассемблер освой, непонимание основ подводит тебя и из-за этого ты какую то фигню размусолил аж на пять страниц
0
БТР - мой друг
333 / 277 / 47
Регистрация: 07.01.2010
Сообщений: 1,932
25.06.2011, 20:57  [ТС] 47
pito211, позже я доберусь и до ассемблера, однако пока хочется узнать механизмы.
0
187 / 174 / 18
Регистрация: 22.03.2010
Сообщений: 612
25.06.2011, 21:11 48
да уже сто раз тут все механизмы обсудили, указатели разжевали как только могли, а ты до сих пор задаёшь одни и те же вопросы. Про виртуальную память всё подробно расписано в книге, которую я привёл выше. Может лучше её открыть, а не дёргать других людей по пустякам, уж наверно у них есть дела поважнее, чем цитирование литературы, находящейся в свободном доступе? Накрайняк можно в педивикию заглянуть

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

Добавлено через 1 минуту
Цитата Сообщение от Hagrael Посмотреть сообщение
3) Как программа узнает, какие места ОЗУ ей можно занимать (не заняты др. программой), а какие - нет.
на этот вопрос в книге таненбаума целая глава есть ВАП
1
БТР - мой друг
333 / 277 / 47
Регистрация: 07.01.2010
Сообщений: 1,932
25.06.2011, 21:14  [ТС] 49
pito211, в моей книге этих нюансов не описывается, а главу "Указатели" я полностью прошел. Я не заставляю никого помогать и не испытываю злобу на людей этого форума, которые мне не помогают Но будьте добры, не заводите впредь эту тему, если конкретную литературу вы не посоветуете. А эта тема действительно будет полезна не только мне, но и другим новичкам, ведь здесь все изложено кратко.
0
Эксперт С++
1069 / 848 / 60
Регистрация: 30.04.2011
Сообщений: 1,659
25.06.2011, 21:23 50
Hagrael, немного про адреса и указатели.
Память - это массив байтов. А элементы массива, как ты знаешь, ПРОНУМЕРОВАНЫ. От 0 до n-1.
В 32-битной машине этот массив имеет размер 2^32 = 4 гб.
Номер элемента памяти - это и есть адрес. Это положительное целое число. Указатель - это переменная, которая хранит этот номер-адрес. В С++ принято, что при выводе на экран значение указателя (целое число-номер элемента памяти) выводится в шестнадцатеричной системе.
1
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.06.2011, 10:30 51
Цитата Сообщение от talis Посмотреть сообщение
Ответить можно и так, и так. Один и тот же указатель может хранить адрес любого по размеру куска памяти. Потому, что единственное, что он хранит - это адрес начала этого куска.
С этим связана одна проблема:
C++
1
delee [] p;//Сколько байт здесь освобождать?
. Как решается?

Добавлено через 13 минут
Цитата Сообщение от Hagrael Посмотреть сообщение
Каждая программа думает, что она одна. Обеспечивает эту сладкую иллюзию для эгоистки-программы операционная система. Но мне не до конца понятно вот что: в коде откомпилированного файла не хранится точный адрес переменной, по которому ее надо записать. Ведь если так будет, то по этому адресу может находиться другая переменная, и возникнет конфликт.
Не будет никакого конфликта, так как по данному адресу в локальном виртуальном адресном пространстве (именно так, виртуальная память - это вообще файл на винчестере, ни какого отношения он сюда не имеет, а работает с ним единственная программа - операционная система, так что в нём как раз только физические адреса) нет других программ, чьи данные и код могли оказаться по указанному адресу. Я уже писал про отсебячьи карты, так вот, это карты разных райнонов, у каждой проги свой.
0
БТР - мой друг
333 / 277 / 47
Регистрация: 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;
работает! В чем дело?
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.06.2011, 10:35 53
Цитата Сообщение от Hagrael Посмотреть сообщение
На этапе компиляции переменные являются указателями?
Нет. Но поля элементов таблицы - указатели.
0
БТР - мой друг
333 / 277 / 47
Регистрация: 07.01.2010
Сообщений: 1,932
26.06.2011, 10:36  [ТС] 54
Непонятно вообще, зачем массив делают константой.
0
Заблокирован
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 константность иногда убивает инкапсуляцию.
0
26.06.2011, 11:38
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.06.2011, 11:38
Помогаю со студенческими работами здесь

Есть три переменные. Используя указатели на указатели, поменять значение максимальной и минимальной переменной
Мой код. #include &lt;iostream&gt; #include &lt;stdlib.h&gt; #include&lt;iomanip&gt; using namespace std; ...

Указатели на указатели с числами. Почему можно присвоить число в 4-ый элемент, если массив из 2 элементов?
Есть массив int **mas; mas=new int*; // выделил место под пять строк, верно ? mas=new int;//...

Зачем нужны все эти указатели (или не указатели)
Зачем надо DWORD, HANDLE, LPVOID?

Указатели на указатели, как правильно разыменовать, где ошибка?
1)Есть класс: Shape - абстрактный; у него есть классы наследники: Circle, Triangle. 2)Eсть...


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

Или воспользуйтесь поиском по форуму:
55
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru