2008-09-09 3 views
14

Я предполагаю, что char* = "string" то же самое для char* = new char[6]. Я считаю, что эти строки создаются в куче вместо стека. Так что мне нужно уничтожить их или освободить их память, когда я закончил использовать их или они сами уничтожаются?Нужно ли уничтожать char * = "string" или char * = new char [6]?

ответ

31

Нет. Вам нужно только вручную освобождать строки, когда вы вручную распределяете память самостоятельно, используя функцию malloc (в C) или оператор new (на C++). Если вы не используете malloc или new, тоили строка будет создана в стеке или как константа времени компиляции.

1

Вы не знаете, где хранятся строковые литералы. Он даже может быть только для чтения памяти, так что ваш код должен прочитать:

const char* c = "string"; 

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

4

Это не то же самое. Ваш первый пример - постоянная строка, поэтому он определенно не выделяется из кучи. Второй пример - выделение памяти времени выполнения из 6 символов, и это происходит из кучи. Вы не хотите удалять свой первый пример, но вам нужен delete [] ваш второй пример.

+1

«новый» выделяет память из кучи, никогда из стека. (Если, конечно, вы не переопределили нового оператора.) – 2008-09-09 11:07:07

4

Я принимаю, когда я делаю char* = "string" его то же самое, что и char* = new char[6].

Нет. Что делает первый, это создать константу. Модификация - неопределенное поведение. Но чтобы ответить на ваш вопрос; нет, вам не нужно их уничтожать. И просто примечание, всегда используйте std::string, когда это возможно.

0

новое всегда является распределением, тогда как определение строки inline фактически внедряет данные в самой программе и не может быть изменено (некоторые компиляторы позволяют это с помощью умного трюка, не беспокойтесь).

Некоторые компиляторы строят строки, чтобы вы не могли изменить буфер.

char* const sz1 = "string"; // embedded string, immutable buffer 
char* sz2 = new char[10]; // allocated string, should be deleted 
17

Нет. Когда вы говорите:

const char* c = "Hello World!"; 

Вы назначаете С к «предварительно существующей» строковой константе, которая не является такой же, как:

char* c = new char[6]; 

только в В последнем случае вы выделяете память в кучу. Таким образом, вы будете называть delete, когда закончите.

3

Название игры «уничтожить только то, что вы создали».Вот пары:

  1. malloc/free
  2. calloc/free
  3. new/delete
  4. new []/delete []

Поскольку вы создали 2-ю строку, используя new [], бремя ответственности является на вас, чтобы уничтожить его с помощью delete []. Позвоните по телефону delete [] string2, когда закончите.

Теперь, если ваш код достаточно сложный и затрудняет отслеживание удалений, рассмотрите использование указателей с областью или автоматических указателей. Класс boost::scoped_ptr из библиотеки boost - это хорошее место для начала. Также обратите внимание на идиому RAII, довольно удобный и полезный материал.

0

Давайте посмотрим, что делает 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); 
} 

Compile и декомпилировать:

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