Распределение строк c ++ - PullRequest
       16

Распределение строк c ++

7 голосов
/ 06 октября 2010

мне нужно позаботиться о распределении памяти, объеме и удалении c ++ "строкового" объекта?

например:

#include <string>

const char* func1() {
   const char* s = "this is a literal string";
   return s;
}

string func2() {
   std::string s = "this is a literal string";
   return s;
}

const char* func3() {
   std::string s = "this is a literal string";
   return s.c_str();
}

void func() {
   const char*  s1 = func1();
   std::string s2 = func2();
   const char*  s3 = func3();

   delete s1; //?
   delete s3; //?
}

func2: мне не нужно «удалять» s2. func3: мне нужно «удалить s3»?

Кстати, func1 правильный? Содержимое памяти персонажа остается доступным после выхода из области действия func1? Если да, я должен удалить его, когда он мне больше не нужен?

Ответы [ 4 ]

16 голосов
/ 06 октября 2010
  • func1() возвращает указатель на строковый литерал.Вы не должны удалять строковые литералы.
  • func2() (предположительно, вы не указали префикс std::) возвращает std::string.Это заботится о себе.
  • func3() возвращает указатель на строку, управляемую объектом std::string, который уничтожается при выходе из функции.Вы не должны касаться этого указателя после возврата функции.
  • Вы должны позаботиться о памяти, возвращаемой этой функцией:

    const char* func4() {
       char* s = new char[100];
       // fill char array with a string
       return s;
    }
    

Однако ручное управление ресурсами является сложной задачей.Для начала, если функция возвращает пустой указатель, вы не знаете, указывает ли она на один объект (char) или на его массив и нужно ли его удалять.Вам следует избегать всего этого и просто придерживаться std::string.

3 голосов
/ 06 октября 2010

У вас другая проблема с s3, а именно то, что функция func3 () возвращает указатель на объект, который выходит из области видимости при выходе из функции. Не.

Для пояснения : Ваш локальный строковый объект в функции func3 () перестанет существовать при возврате функции, поэтому нет необходимости удалять. Однако у вас все еще есть указатель на его внутренний буфер, который вы возвращаете. Вы не можете использовать это.

Очень хороший и подробный прошлый ответ здесь, чтобы не возникало путаницы: Более эффективно возвращать константную ссылку

1 голос
/ 06 октября 2010

В func3 ваша строка local создается компилятором, вызывающим неявный конструктор string(const char*), который инициализирует свой внутренний буфер копией строкового литерала.Затем вы возвращаете указатель на внутренний буфер строки, который быстро выходит из области видимости и освобождается, как только возвращается функция.

1 голос
/ 06 октября 2010

Я снимаю соответствующий код для каждой функции и обработки ее возвращаемого значения, и комментирую ниже:

const char* func1() {
   const char* s = "this is a literal string";
   return s;
}
const char*  s1 = func1();
delete s1; //?

Вы не можете удалить s1, поскольку строка, на которую она указывает, не живеткуча.

string func2() {
   string s = "this is a literal string";
   return s;
}
string s2 = func2();

Это нормально.func2 s s выходит из области видимости и очищается.s2 продублирует строку из s, а также очистит себя в конце func.

const char* func3() {
   string s = "this is a literal string";
   return s.c_str();
}
const char*  s3 = func3();
delete s3; //?

func3 вернет указатель на освобожденную строку.Вы получите двойное бесплатное исключение при исполнении delete s3.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...