我知道这是C中的一个坏事情,但是我没有找到一个C++的肯定答案。,c++,memory-leaks,C++,Memory Leaks" /> 我知道这是C中的一个坏事情,但是我没有找到一个C++的肯定答案。,c++,memory-leaks,C++,Memory Leaks" />

在C++;返回从本地字符数组创建的字符串是否会导致内存泄漏或未定义的行为? 我想知道这是否会导致内存泄漏或C++中的未定义结果? string foo() { char tempArray[30]; strcpy(tempArray, "This is a test"); return string(tempArray); } P>我知道这是C中的一个坏事情,但是我没有找到一个C++的肯定答案。

在C++;返回从本地字符数组创建的字符串是否会导致内存泄漏或未定义的行为? 我想知道这是否会导致内存泄漏或C++中的未定义结果? string foo() { char tempArray[30]; strcpy(tempArray, "This is a test"); return string(tempArray); } P>我知道这是C中的一个坏事情,但是我没有找到一个C++的肯定答案。,c++,memory-leaks,C++,Memory Leaks,所以每个人都说不,但我仍然不知道什么时候释放内存 假设我有一个调用上述方法的方法 void bar() { string testString = foo(); } 在上面的代码中,从foo()返回的string对象在什么时候调用其析构函数?它是在被复制到对象testString之后立即执行的吗?不是特别有效,但是没有,没有泄漏。没有,它不会导致任何泄漏,因为您从不在堆上分配内存。如果使用了malloc,calloc或new。。而且你永远都不会免费删除它。然后是的,内存泄漏 数组是静态

所以每个人都说不,但我仍然不知道什么时候释放内存

假设我有一个调用上述方法的方法

void bar()
{
    string testString = foo();
}

在上面的代码中,从foo()返回的string对象在什么时候调用其析构函数?它是在被复制到对象testString之后立即执行的吗?

不是特别有效,但是没有,没有泄漏。

没有,它不会导致任何泄漏,因为您从不在堆上分配内存。如果使用了
malloc
calloc
new
。。而且你永远都不会免费删除它。然后是的,内存泄漏


数组是静态分配的,因此它是在堆栈上创建的
strcpy
不返回动态分配的对象,它填充现有数组,它知道如何执行此操作,因为您传入了指针—同样,不是在堆上分配的。当您返回字符串时,将创建字符串对象的副本。

不,没有内存泄漏,您不需要执行所有这些操作,这里与您的代码等效

string foo()
{
 return "This is a test";
}

始终可以按值从函数返回局部自动变量。对于任何类型,这都应该是安全的(除非复制构造函数不安全):

或:

你的例子与我的第一个案例相符

不安全的是返回本地自动变量的指针/引用:

T& foo()
{
   T t
   return t;
}

T* foo()
{
   T t
   return &t;
}

在您的示例中发生的是,具有签名的构造函数

字符串(常量字符*s)

被称为。构造函数为字符串的副本分配新内存,并将其复制到新内存中。然后,字符串对象负责在调用其析构函数时释放自己的内存

创建字符串副本时,也会分配内存并创建副本

您还应该查看模式。这就是
字符串的内存管理工作原理。

在此代码中:

char tempArray[30];
tempArray
是一个具有自动存储持续时间的变量。当
tempArray
“超出范围”时,它会自动销毁。将此数组的内容(有些笨拙)复制到
std::string
中,然后按值返回该
string
。然后
tempArray
被销毁。信息技术这里需要注意的是,
tempArray
是数组。它不是指向数组的第一个元素的指针(这通常是错误的),而是数组本身。由于
tempArray
被销毁,因此该数组被销毁

如果使用具有动态存储持续时间的变量,例如:

  char* tempArray = new char[30];
  strcpy(tempArray, "This is a test");
  return string(tempArray);

注意
new[]
没有匹配的
delete[]
。这里,
tempArray
仍然是一个具有自动存储持续时间的变量,但这次它是一个指针,它指向的对象具有动态存储持续时间。换句话说,
tempArray
在超出范围时被销毁,但它只是一个指针。它指向的东西--
char
数组本身并没有被破坏,因为您不
delete[]
它。

谢谢。。你知道为什么吗?如果不在返回值的寄存器中,字符串存储在哪里?以后如何清理呢?它由string对象存储,并且依赖于实现。最有可能的情况是,它位于堆上,当字符串变量超出范围时,它将从堆中释放。在您的示例中,当
foo()
的调用方超出其作用域时。在您的示例中,存储了一个静态字符串。。。在我的中,我有一个临时数组,当它返回指向数组的指针时,该数组将不再包含刚刚堆栈弹出的临时数组garbage@BeenCoding2Long:否,您的代码不会返回临时数组,而是将其内容复制到字符串中。在这两种情况下,返回的都是一个
string
对象,其值是其他内容的副本,但它与string对象的副本没有区别。啊,好的,我明白了,谢谢!我已经用C编写了很长时间了,我很难习惯对象的东西。你应该知道,在代码中有一个隐式构造函数调用。C字符串“这是一个测试”被隐式转换为
std::string
,因为构造函数没有声明为
explicit
@JørgenFogh:
还包含一个隐式构造函数调用——指向C++03中的
string
的复制构造函数,C++11中的移动构造函数。与更明显的
返回“这是一个测试”相比,它似乎没有太多必要……作为旁白,你对这里的答案的评论强烈地给你的印象是你认为C++是C或类似C的,它不是。是的,我知道。我还在想办法解决问题。这是编译还是打字错误:
stringteststring=stringfoo()?这是一个输入错误,现在已经修复了,所以创建并返回了一个完整的字符串对象。就像我返回了一个本地结构,对象跟踪字符串的大小和分配位置一样?创建一个新的字符串对象,并将所有字符复制到该字符串对象中。但当您返回该字符串时,它将返回字符串对象的另一个副本。那个物体知道它的长度和所有这些。
char tempArray[30];
  char* tempArray = new char[30];
  strcpy(tempArray, "This is a test");
  return string(tempArray);