Нужно ли уничтожать 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[]. Поэтому вы должны освободить его, когда сможете.