Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.80/5: Рейтинг темы: голосов - 5, средняя оценка - 4.80
2 / 5 / 1
Регистрация: 13.09.2015
Сообщений: 100
1

Указатели и динамическая память

22.10.2015, 23:08. Показов 1015. Ответов 22
Метки нет (Все метки)

Не могу немного понять, допустим, я хочу создать массив, зачем мне под него выделять память, почему нельзя создать указатель, инициализировать его и просто с помощью адресной арифметики переходить к другому члену массива?
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
22.10.2015, 23:08
Ответы с готовыми решениями:

Указатели и Динамическая память
Создать в динамической памяти массив вещественных чисел размерности R. Заполнить его случайными...

Указатели. Динамическая память в С++
Найти наибольшую и наименьшую цифры в записи данного натурального числа. У меня есть код на...

Динамическая память, указатели
есть два вектора структуры s1 нужно поместить в элемент вектора указатель на следующий, в...

Указатели. Динамическая память.
Нужно очень срочно. Сегодня последний день сдачи. 1. Дано натуральное число n. Определить...

22
Jesus loves me
Эксперт С++
5189 / 3157 / 355
Регистрация: 12.12.2009
Сообщений: 7,973
Записей в блоге: 2
22.10.2015, 23:16 2
Если указатель инициализировать валидным значением (адресом заранее выделенной памяти), то можно и так.
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
22.10.2015, 23:35 3
Цитата Сообщение от ChadloveMary Посмотреть сообщение
Не могу немного понять, допустим, я хочу создать массив, зачем мне под него выделять память, почему нельзя создать указатель, инициализировать его и просто с помощью адресной арифметики переходить к другому члену массива?
Допустим, я хочу создать дом. Зачем мне под него покупать землю, почему нельзя просто поставить палатку прямо на автостраде и сказать чтоб почту приносили туда? Да потому что вон тот грузовик уже считает автостраду своей и палатку переедет. Тоже самое с выделением памяти, оно нужно чтоб застолбить область памяти за собой любимым.
3
31 / 31 / 5
Регистрация: 24.09.2014
Сообщений: 243
22.10.2015, 23:43 4
Цитата Сообщение от ChadloveMary Посмотреть сообщение
инициализировать его
Это и будет выделение памяти. Иначе операционка не допустит обращения по этому адресу и выше.
0
Don't worry, be happy
17170 / 10053 / 1935
Регистрация: 27.09.2012
Сообщений: 25,045
Записей в блоге: 1
23.10.2015, 00:00 5
Цитата Сообщение от panotnap Посмотреть сообщение
Это и будет выделение памяти
"инициализация указателя" != "выделение памяти"
1
31 / 31 / 5
Регистрация: 24.09.2014
Сообщений: 243
23.10.2015, 02:00 6
Добавлено через 54 минуты
Цитата Сообщение от Croessmah Посмотреть сообщение
"инициализация указателя" != "выделение памяти"
Может быть, я в терминологии могу ошибаться. Для меня "инициализацировать" означало - и выделить память, и получить ссылку, в неразрывной связи. А речь идёт только о создании указателя на адрес, что трудно воспринимать как инициализацию.
0
3413 / 2772 / 751
Регистрация: 25.03.2012
Сообщений: 10,082
Записей в блоге: 1
23.10.2015, 19:40 7
Croessmah, да ладно? Серьёзно что ли?

C++
1
2
int *x;
x=new int;//а здесь что, не инициализация что ли?
ППц народ бухает по пятницам...
0
2723 / 1887 / 559
Регистрация: 05.06.2014
Сообщений: 5,499
23.10.2015, 19:42 8
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Croessmah, да ладно? Серьёзно что ли?
C++
1
2
int x;
int*p=&x;//здесь что, выделение памяти что ли?
0
3413 / 2772 / 751
Регистрация: 25.03.2012
Сообщений: 10,082
Записей в блоге: 1
23.10.2015, 21:13 9
Renji, а ты чё, Croessmah, что ли?
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
ППц народ бухает по пятницам...
0
26 / 26 / 17
Регистрация: 08.04.2012
Сообщений: 202
23.10.2015, 22:06 10
Цитата Сообщение от ChadloveMary Посмотреть сообщение
Не могу немного понять, допустим, я хочу создать массив, зачем мне под него выделять память, почему нельзя создать указатель, инициализировать его и просто с помощью адресной арифметики переходить к другому члену массива?
Все очень просто, когда ты знаешь сколько элементов будет в массиве ты не используете динамическое выделение памятичто то вроде
C++
1
char r[10];
, а вот когда ты не знаешь сколько элементов будет(например пользователь вводить информацию с клавиатуры) можно либо сделать про запас
C++
1
char r[100];
, либо использовать динамическое выделение памяти и при каждом выполнении программы будет создаваться массив разных размеров.
0
Don't worry, be happy
17170 / 10053 / 1935
Регистрация: 27.09.2012
Сообщений: 25,045
Записей в блоге: 1
24.10.2015, 00:45 11
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
да ладно? Серьёзно что ли?
вроде не лето, а перегрелся...
C++
1
int * x = nullptr ; //А здесь неинициализированный указатель или память выделили???
0
31 / 31 / 5
Регистрация: 24.09.2014
Сообщений: 243
24.10.2015, 05:01 12
Вопрос не существенный, конечно, но...
Инициализация (от англ. initialization, инициирование) — создание, активация, подготовка к работе, определение параметров. Приведение программы или устройства в состояние готовности к использованию.
и ещё
действие по значению гл. инициализировать; процесс подготовки чего-либо к работе
действие по значению гл. инициализировать; определение чего-либо, присвоение значений переменным программы
инициализировать - задать начальные значения какому-либо объекту, обеспечивая возможность работать с ним.
...то есть инициализация предполагает то, что то, что иницилизированно, будет работать или, по крайней мере, готово к работе.

А в нашем случае это действие имеет экспериментальный характер и готовность к работе ставится под принципиальный вопрос, так что, строго говоря, инициализацией создание указателя называть весьма сомнительно. Ты ещё не знаешь, способна ли работать предложенная схема действий или нет; поэтому не можешь инициализировать то, что, возможно, не инициализируемо.

Ещё имеет место быть предположительно не совсем правильное применение слова "инциализировать". Думаю, не совсем корректно применять это слово в программировании ко всему подряд: я ин. переменную, ин. цикл, ин. условный переход, ин. функцию, ин. пятнадцатый бит третьего байта (это же всё подготовка к работе) и т. д. Больше для этого слова подходит, на мой взгляд, значение, передающее довольно крупное действие: инициализация базы данных... инициализация компьютера... инциализация системы печати...

То есть мне кажется, что создание указателей и аллокация памяти - это всё вместе и есть одна инициализация (и то с натяжкой, ибо весьма мелкая).
0
Don't worry, be happy
17170 / 10053 / 1935
Регистрация: 27.09.2012
Сообщений: 25,045
Записей в блоге: 1
24.10.2015, 14:20 13
Цитата Сообщение от panotnap Посмотреть сообщение
нициализировать - задать начальные значения какому-либо объекту, обеспечивая возможность работать с ним.
то есть int * x = nullptr ; как раз инициализация указателя. Задали нужное нам значение (при создании указателя), чтобы можно было с ним работать.

Ну коли ссылку лочит, перенесу вопрос и ответ на форум.

Вопрос:
Запутался в терминах. Всё осложняется тем, что в разных книгах они описаны по-разному. Например, когда происходит инициализация, в момент объявления переменной или в момент первой передачи ей значения? Ниже список операторов. Что, по-вашему, представляет каждый из них?
C++
1
2
3
4
5
int main(){
   int x; //Инициализация без присвоения? Или всё-таки просто определение без инициализации? Хотя переменная, по идее, должна содержать некое "мусорное" значение, значит она инициализирована?
   double y=2.1;
   x=3;
}
Ответ:
C++
1
2
    int x;
    double y=2.1;
Это declaration statement

Пункт 3.1/2 стандарта гласит

A declaration is a definition unless it declares a function without specifying the function’s body (8.4), it contains the extern specifier (7.1.1) or a linkage-specification 25 (7.5) and neither an initializer nor a function-body, it declares a static data member in a class definition (9.4), it is a class name declaration (9.1), it is an opaque-enum-declaration (7.2), or it is a typedef declaration (7.1.3), a using-declaration (7.3.3), a static_assert-declaration (Clause 7), an attribute-declaration (Clause 7), an empty-declaration (Clause 7), or a using-directive (7.3.4).
то есть в данном случае int x; и double y=2.1; это и объявление и определение.

т.к. переменные x и y объявлены внутри функции, то они "automatic storage duration", и к ним применяется правило

Variables with automatic storage duration (3.7.3) are initialized each time their declaration-statement is executed. Variables with automatic storage duration declared in the block are destroyed on exit from the block
Разберем запись

C++
1
int x ;
Обратимся к стандарту c++ (пункт 8.5/11)

If no initializer is specified for an object, the object is default-initialized; if no initialization is performed, an object with automatic or dynamic storage duration has indeterminate value.
В нашем случае переменная будет default-initialized и будет иметь неопределенное значение. Посмотрим в стандарте что такое default-initialize (пункт 8.5/6)

To default-initialize an object of type T means:

— if T is a (possibly cv-qualified) class type (Clause 9), the default constructor for T is called (and the initialization is ill-formed if T has no accessible default constructor);

— if T is an array type, each element is default-initialized;

otherwise, no initialization is performed.
У нас переменная не классового типа и не массив, поэтому нас интересует только последний случай, из которого можно сделать вывод, что в данном случае инициализация не выполняется.

Разберем теперь строчку

C++
1
double y=2.1;
Также обратимся к стандарту (пункт 8.5/13)

The form of initialization (using parentheses or =) is generally insignificant, but does matter when the initializer or the entity being initialized has a class type; see below. A parenthesized initializer can be a list of expressions only when the entity being initialized has a class type.
То есть для double разницы между double y=2.1; и double y(2.1); фактически не будет. Далее (пункт 8.5/16)

Otherwise, the initial value of the object being initialized is the (possibly converted) value of the initializer expression. Standard conversions (Clause 4) will be used, if necessary, to convert the initializer expression to the cv-unqualified version of the destination type; no user-defined conversions are considered. If the conversion cannot be done, the initialization is ill-formed.
Вывод: в данном случае double будет инициализирована значением 2.1. И это будет именно инициализация, а не присваивание.

C++
1
x=3;
Это expression statement (пункт 6.2/1)

Expression statements have the form

expression-statement:
expression_opt ;
The expression is evaluated and its value is discarded. The lvalue-to-rvalue (4.1), array-to-pointer (4.2), and function-to-pointer (4.3) standard conversions are not applied to the expression. All side effects from an expression statement are completed before the next statement is executed. An expression statement with the expression missing is called a null statement. [ Note: Most statements are expression statements — usually assignments or function calls. A null statement is useful to carry a label just before the } of a compound statement and to supply a null body to an iteration statement such as a while statement (6.5.1). — end note ]
Здесь у нас в expression_opt имеется assignment operator (пункт 5.17)

1. The assignment operator (=) and the compound assignment operators all group right-to-left. All require a modifiable lvalue as their left operand and return an lvalue referring to the left operand. The result in all cases is a bit-field if the left operand is a bit-field. In all cases, the assignment is sequenced after the value computation of the right and left operands, and before the value computation of the assignment expression.

2. In simple assignment (=), the value of the expression replaces that of the object referred to by the left operand.

3. If the left operand is not of class type, the expression is implicitly converted (Clause 4) to the cv-unqualified type of the left operand.
Вывод: в результате x станет равным 3 и "=" в данном случае будет означать именно "присваивание".
0
31 / 31 / 5
Регистрация: 24.09.2014
Сообщений: 243
24.10.2015, 17:14 14
инициализировать - задать начальные значения какому-либо объекту, обеспечивая возможность работать с ним.
Цитата Сообщение от Croessmah Посмотреть сообщение
то есть int * x = nullptr ; как раз инициализация указателя. Задали нужное нам значение (при создании указателя), чтобы можно было с ним работать.
И как Вы будете работать с пустым-то указателем? Вы его недоинициализировали.

C++
1
2
3
4
5
6
/*  Начинаем ИНИЦИАЛИЗАЦИЮ.  */
int* mas= NULL;  //  это инициализация? или инициализация_указателя_на_массив?
mas= new int[256];  //  НЕ инициализация? просто аллокация? или можно вообще без неё? :p
int* second= &mas[1];  //  а это что? иницализация №2?
int* last= &mas[255];  // №3...? сколько их? %-)
/*  ИНИЦИАЛИЗАЦИЯ закончена.    */
Цитата Сообщение от Croessmah Посмотреть сообщение
обратимся к стандарту
А давайте к разуму лучше.
0
Don't worry, be happy
17170 / 10053 / 1935
Регистрация: 27.09.2012
Сообщений: 25,045
Записей в блоге: 1
24.10.2015, 17:22 15
Цитата Сообщение от panotnap Посмотреть сообщение
И как Вы будете работать с пустым-то указателем? Вы его недоинициализировали.
Вы реально не в курсе зачем нужен такой указатель?
C++
1
2
3
4
5
6
int * x ;//не инициализированный указатель. Что в нем?
//...
//x мог где-то поменяться, а мог и нет.
//...
if ( x == nullptr ) //ох беда, беда...
   //выполняем действия
int* mas= NULL; // это инициализация? или инициализация_указателя_на_массив?
Это инициализация указателя. Причем здесь указатель на массив? Здесь указатель на int
mas= new int[256]; // НЕ инициализация? просто аллокация? или можно вообще без неё?
Аллокация и присваивание.
Продолжим этот код далее:
C++
1
int * mas2 = mas ; //mas2 в Вашей теории не инициализирован, т.к. память же не запрашивали.
Цитата Сообщение от panotnap Посмотреть сообщение
int* second= &mas[1]; // а это что? иницализация №2?
что такое инициализация №2? Это инициализация указателя second.
Цитата Сообщение от panotnap Посмотреть сообщение
int* last= &mas[255]; // №3...? сколько их?
что за номер три? Еще один указатель инициализировали.

Уважаемый, Вы хрень какую-то пишите...

Цитата Сообщение от panotnap Посмотреть сообщение
А давайте к разуму лучше.
бинарный разум?
1
castaway
24.10.2015, 18:17
  #16

Не по теме:

Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
ППц народ бухает по пятницам...
Скажу честно, он и по субботам бухает:D (народ, не Croessmah)

0
Croessmah
24.10.2015, 18:19
  #17

Не по теме:

Цитата Сообщение от castaway Посмотреть сообщение
Скажу честно, он и по субботам бухает (народ, не Croessmah)
мне сейчас на работу, так что черт его знает что там будет :D

0
31 / 31 / 5
Регистрация: 24.09.2014
Сообщений: 243
24.10.2015, 20:44 18
Croessmah, Вы не улавливаете смысл.
Занять горизонтальное положение - это ещё НЕ ЛЕЧЬ, ровно как и коснуться телом дивана.

Вы касаетесь телом дивана, стоящего на торце (допустим, ремонт) и утверждаете: "Я сейчас ложусь на диван...".
Далее, оттолкнувшись ногой, Вы грохаетесь вместе с ним на пол и произносите: "А это просто поворот на 90 градусов!"

0
Эксперт С++
4974 / 3081 / 456
Регистрация: 10.11.2010
Сообщений: 11,160
Записей в блоге: 10
24.10.2015, 20:50 19
panotnap, скажи, пожалуйста, что из следующего инициализация. Просто для того, чтобы я (возможно кто-то ещё) начал улавливать мысль...
C++
1
2
3
4
5
int i;
int * p1 = nullptr;
int * p2;
int * p3 = &i;
p2 = p1;
1
Don't worry, be happy
17170 / 10053 / 1935
Регистрация: 27.09.2012
Сообщений: 25,045
Записей в блоге: 1
24.10.2015, 21:00 20
Цитата Сообщение от castaway Посмотреть сообщение
пожалуйста, что из следующего инициализация.
по его теории ничего, ведь нет же выделения памяти
Цитата Сообщение от panotnap Посмотреть сообщение
Вы касаетесь телом дивана, стоящего на торце (допустим, ремонт) и утверждаете: "Я сейчас ложусь на диван...".
нет, не я

Цитата Сообщение от panotnap Посмотреть сообщение
Вы не улавливаете смысл.
Поясните лучше тогда, а не бред про диван и хрен пойми какие-то номера инициализации.
1
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
24.10.2015, 21:00

Указатели и динамическая память
Здравствуйте. Почему размер памяти для указателя выделяется такой же как для объекта в куче....

Указатели.Динамическая память.
Перепешите пожалуйста на С/С++! <script> var n = new Number(); var m = new Number(); n =...

Массивы и указатели. Динамическая память
Нужно вывести на экран максимальные элементы в каждом столбце двумерного массива (матрицы). Решить...

Указатели и динамическая память new delete
Начал работать умными указателями, в итоге как понял не сильно освоил то и Cи указатели. 1) В...


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

Или воспользуйтесь поиском по форуму:
20
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2021, vBulletin Solutions, Inc.