Есть ли необходимость уничтожать char * = "string" или char * = new char [6]? - PullRequest
14 голосов
/ 09 сентября 2008

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

Ответы [ 8 ]

31 голосов
/ 09 сентября 2008

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

17 голосов
/ 09 сентября 2008

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

const char* c = "Hello World!";

Вы присваиваете c «существующей» строковой константе, которая НЕ совпадает с:

char* c = new char[6];

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

4 голосов
/ 12 сентября 2010

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

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

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

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

4 голосов
/ 09 сентября 2008

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

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

3 голосов
/ 09 сентября 2008

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

1 голос
/ 09 сентября 2008

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

const char* c = "string";

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

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);
}

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

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

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

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

char* const sz1 = "string"; // embedded string, immutable buffer
char* sz2 = new char[10]; // allocated string, should be deleted
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...