Нужно ли уничтожать char * = "string" или char * = new char [6]?
Я предполагаю, что char* = "string"
совпадает с char* = new char[6]
. Я считаю, что эти строки создаются в куче вместо стека. Так что мне нужно уничтожить их или освободить их память, когда я закончил использовать их или они сами уничтожаются?
Ответы
Ответ 1
Нет. Вам просто нужно вручную освобождать строки, когда вы вручную выделяете память самостоятельно, используя функцию malloc
(в C) или оператор new
(на С++). Если вы не используете malloc
или new
, то строка char*
или будет создана в стеке или как константа времени компиляции.
Ответ 2
Нет. Когда вы говорите:
const char* c = "Hello World!";
Вы назначаете c "ранее существующей" строковой константе, которая НЕ совпадает с:
char* c = new char[6];
Только в последнем случае вы выделяете память в кучу. Таким образом, вы будете называть delete, когда закончите.
Ответ 3
Они не то же самое. Ваш первый пример - постоянная строка, поэтому он определенно не выделяется из кучи. Второй пример - выделение памяти времени выполнения из 6 символов, и это происходит из кучи. Вы не хотите удалять свой первый пример, но вам нужно delete []
ваш второй пример.
Ответ 4
Я предполагаю, что когда я делаю char* = "string"
то же самое, что и char* = new char[6]
.
Нет. Что первый делает, это создать константу. Модификация - поведение undefined. Но чтобы ответить на ваш вопрос; нет, вам не нужно их уничтожать. И просто заметьте, всегда используйте std::string
, когда это возможно.
Ответ 5
Название игры - "уничтожить только то, что вы создали". Вот пара:
-
malloc
/free
-
calloc
/free
-
new
/delete
-
new []
/<Т27 >
Так как вы создали 2-ю строку с помощью new []
, то на вас стоит уничтожить ее с помощью delete []
. Вызовите delete [] string2
, когда вы закончите.
Теперь, если ваш код достаточно сложный и затрудняет отслеживание удаления, рассмотрите использование указателей с областью или указателей автозапуска. boost::scoped_ptr
класс из библиотеки boost - это хорошее место для начала. Также рассмотрите RAII, довольно удобный и полезный материал.
Ответ 6
Вы не знаете, где хранятся строковые литералы. Это может быть даже память, доступная только для чтения, поэтому ваш код должен читать:
const char* c = "string";
И новый массив char должен быть удален так же, как любая другая динамически выделенная область памяти.
Ответ 7
new всегда является распределением, тогда как определение строки inline фактически внедряет данные в самой программе и не может быть изменено (некоторые компиляторы позволяют это с помощью умного трюка, не беспокойтесь).
Некоторые компиляторы строят строки, чтобы вы не могли изменять буфер.
char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted
Ответ 8
Посмотрите, что делает GCC 4.8 x86-64 Linux
Программа:
#include <cstdio>
int main() {
const char *s = "abc";
char *sn = new char[4];
sn[3] = '\0';
std::printf("%s\n", s);
std::printf("%s\n", sn);
}
Скомпилировать и декомпилировать:
g++ -ggdb -std=c++98 a.cpp
objdump -CSr a.o
Вывод содержит:
const char *s = "abc";
8: 48 c7 45 f0 00 00 00 movq $0x0,-0x10(%rbp)
f: 00
c: R_X86_64_32S .rodata
char *sn = new char[4];
10: bf 04 00 00 00 mov $0x4,%edi
15: e8 00 00 00 00 callq 1a <main+0x1a>
16: R_X86_64_PC32 operator new[](unsigned long)-0x4
1a: 48 89 45 f8 mov %rax,-0x8(%rbp)
Интерпретация:
-
char *s = "abc"
переходит в .rodata
. Таким образом, вы не можете free
его каким-либо образом.
-
char *sn = new char[4];
выводится на выходе operator new[]
. Поэтому вы должны освободить его, когда сможете.