Проблема с пониманием того, как работают указатели и «новые» - PullRequest
0 голосов
/ 29 марта 2012

В настоящее время я изучаю указатели в моей книге C ++ (Программирование: Принципы и практика с использованием C ++ от Страуструпа).Книга заставила меня сделать следующее «упражнение», чтобы привыкнуть к указателям и массивам.Я прокомментировал части упражнения, которые не имеют отношения к моей проблеме.

int num = 7;
int* p1 = #

// output p1 address and content...

int* p2 = new int(10);

// initialise each element, and output content...

int* p3 = p2;
p1 = p2;

// output p1 and p2 address and content...

delete[] p1;

/* As all pointers now point to the same array created in the free store, 
   I was under the impression that I only needed to use delete for 1 of 
   the pointers to deallocate memory,as above, but the program crashes 
   if I don't do it for all 3 and execute next section of code? */

p1 = new int(10);
p2 = new int(10);

// Initialise each array to a different range of numbers using a loop,
// output each array, change elements in p2 to be the same as p1, output...

delete[] p1;
delete[] p2;

В последней части у меня возникли проблемы.При выводе каждого массива значения элементов совпадают.Я предполагаю, что p1 все еще == p2, из-за кода несколькими строками раньше.Я думал, что когда вы используете ключевое слово «new», оно возвращает адрес, ссылаясь на другой, недавно выделенный блок памяти, и поэтому p1 больше не будет == p2.Единственный способ заставить его работать - это напрямую создать 2 массива и сделать так, чтобы p1 и p2 ссылались на них с помощью оператора &.Любое объяснение того, что я делаю неправильно, приветствуется.

Ответы [ 2 ]

2 голосов
/ 29 марта 2012

Проблема, вероятно, связана с тем, что когда вы говорите

p = new int(10)

Вы выделяете ОДНО целое число и инициализируете его 10, а не массив размером 10.

2 голосов
/ 29 марта 2012
int* p2 = new int(10);

// initialise each element, and output content...

int* p3 = p2;
p1 = p2;

// output p1 and p2 address and content...

delete[] p1;

Этот код приводит к неопределенному поведению , потому что вы выделяете с помощью new и освобождаете память с помощью delete[].

int* p2 = new int(10);
//allocates a single int with value 10

отличается от

int* p2 = new int[10];
//allocates an uninitialized array of 10 ints

Помимо этого (хотя это серьезная проблема, как и все неопределенное поведение), проблема заключалась в следующем:

int* p2 = new int(10);
int* p3 = p2;
p1 = p2;
//all pointer point to the same memory location

delete[] p1;
//delete that memory
//all three pointers are now invalid

Попытка снова освободить память с помощью delete p2 или delete p3 снова приведет к неопределенному поведению и, возможно, к падению, поскольку вы уже удалили эту память. Вот почему выделение новой памяти исправит сбой.

Итог: не освобождайте одну и ту же память несколько раз.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...