4

我想知道这是否会导致 C++ 中的内存泄漏或未定义的结果?

string foo()
{
    char tempArray[30];
    strcpy(tempArray, "This is a test");
    return string(tempArray);
}

我知道这在 C 中是一件坏事,但我还没有找到 C++ 的明确答案。

所以每个人都说不,但我仍然对何时释放内存感到困惑?

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

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

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

4

6 回答 6

2

不,没有内存泄漏,你不需要做所有这些,这里相当于你的代码

string foo()
{
 return "This is a test";
}
于 2012-11-16T22:17:56.267 回答
2

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

string ( const char * s );

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

复制字符串时,复制构造函数也会分配内存并进行复制。

您还应该查看RAII模式。这就是string内存管理的工作方式。

于 2012-11-16T22:21:43.740 回答
2

在这段代码中:

char tempArray[30];

tempArray是一个具有自动存储持续时间的变量。当tempArray“超出范围”时,它会自动销毁。您将此数组的内容(有些笨拙)复制到 a 中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[]

于 2012-11-16T22:27:03.397 回答
1

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

于 2012-11-16T22:16:02.620 回答
1

不,它不会导致任何泄漏,因为您从不在堆上分配内存。如果您使用过malloc,callocnew.. 而您从不free/delete它。然后是的,内存泄漏!

该数组是静态分配的,因此它是在堆栈上创建的。strcpy不返回动态分配的对象,它填充现有数组,由于您传入的指针,它知道如何执行此操作 - 再次,未在堆上分配。返回字符串时会生成字符串对象的副本。

于 2012-11-16T22:17:24.177 回答
0

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

T foo()
{
   return T(...);
}

或者:

T foo()
{
   T t
   return t;
}

你的例子符合我的第一个案例。

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

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

T* foo()
{
   T t
   return &t;
}
于 2012-11-16T22:20:26.790 回答