Использование указания размера при динамическом распределении памяти - PullRequest
0 голосов
/ 08 мая 2019

Я пытаюсь понять, каково точное использование указания размера при динамическом выделении памяти с использованием нового ключевого слова и какую роль оно играет, когда освобождается эта память.

 char* c = new char; // Not specifying size here
 c[0] = 'h';
 c[1] = 'i';
 c[2] = '\0';
 delete c;        

 char* d = new char[3];
 d[0] = 'h';
 d[1] = 'i';
 d[2] = '\0';
 delete[] d;

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

И, насколько я понимаю, для отслеживания распределения памяти и для правильного ее освобождения при необходимости требуется указание размера.Пожалуйста, предоставьте некоторую информацию по этой части.

Ответы [ 3 ]

3 голосов
/ 08 мая 2019

Первая версия кода выделяет место для одного символа, это совершенно правильно, вы можете выделить одну вещь с помощью new или массив вещей с помощью new[].Беда в том, что вы идете и топаете всю память, которой у вас нет , что является неопределенным поведением.

Ничего не происходит неправильно, когда вы вызываете delete, вы удаляетедействительный, ранее выделенный указатель.Что может пойти не так, если вы изменяете память, которой не владеете.

Во втором случае вы выделяете 3 символа, и манипуляции действительны.

Обратите внимание, что в C ++ вам следуетиспользовать std::string для строковых данных, std::vector для переменной длины или std::array для фиксированной длины.

2 голосов
/ 08 мая 2019

Указание размера выделяет массив. Если ваш тип int[3], он выделит место для 3 int. Если тип просто int, он выделит только достаточно памяти для 1 int.

И, насколько я понимаю, для отслеживания распределения памяти и правильного ее освобождения при необходимости требуется указание размера. Пожалуйста, предоставьте некоторую информацию по этой части.

Вам необходимо отслеживать, сколько памяти вы выделили, чтобы не выходить за пределы. Что касается освобождения памяти, delete и delete[] просто работают. Они обрабатывают освобождение правильного объема памяти независимо от того, отслеживаете ли вы ее в программе.

1 голос
/ 08 мая 2019

"что еще может пойти не так в этом сценарии"

Ну, это неопределенное поведение. Это означает, что все гарантии ушли - навсегда. Жесткий диск отформатирован? Все может пойти не так, как надо.

Просто используйте std::string. Это экономит жесткие диски.

...