c ++字符串分配

时间:2010-10-06 13:58:59

标签: c++ string memory

我需要处理关于c ++“string”对象的内存分配,范围和删除吗?

例如:

#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 个答案:

答案 0 :(得分:16)

  • 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

答案 1 :(得分:3)

你对s3有一个不同的问题,即函数func3()在函数返回时返回一个超出范围的对象的指针。不。

澄清:func3()中的本地字符串对象将在函数返回时停止存在,因此无需删除。但是,您仍然有一个指向其内部缓冲区的指针,您将返回该指针。你无法使用它。

这里非常好,详细的过去答案,以免产生更多混乱:Is it more efficient to return a const reference

答案 2 :(得分:1)

我将相关代码剪切到每个函数并处理其返回值,并在下面发表评论:

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的{​​{1}}超出了范围并进行了清理。 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后,您将获得双重免费例外。

答案 3 :(得分:1)

在func3中,您的字符串本地是由编译器调用隐式构造函数string(const char*)创建的,其内部缓冲区使用字符串文字的副本进行初始化。然后返回一个指向字符串内部缓冲区的指针,该指针会立即超出范围,并在函数返回后立即释放。