Есть ли необходимость уничтожить char * = «строка» или char * = new char[6]?

StackOverflow https://stackoverflow.com/questions/51592

  •  09-06-2019
  •  | 
  •  

Вопрос

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

Это было полезно?

Решение

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

Другие советы

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

const char* c = "Hello World!";

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

char* c = new char[6];

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

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

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

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

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

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

Теперь, если ваш код достаточно запутан и затрудняет отслеживание удалений, рассмотрите возможность использования указателей с ограниченной областью или автоматических указателей.А boost::scoped_ptr класс из библиотеки boost — хорошее место для начала.Также загляните в РАИИ идиома, довольно удобная и полезная штука.

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

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

const char* c = "string";

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

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

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

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

Давайте посмотрим, что делает 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[].Поэтому вам следует освободить его, когда сможете.
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top