在C++中,返回从本地字符数组创建的字符串是否会导致内存泄漏或未定义的行为
In C++ does returning a string created from a local char array cause a memory leak or undefined behavior?
我想知道这是否会导致C++中的内存泄漏或未定义的结果?
string foo()
{
char tempArray[30];
strcpy(tempArray, "This is a test");
return string(tempArray);
}
我知道这在C中是一件坏事,但我还没有找到C++的确切答案。
所以每个人都说不,但我仍然困惑于内存何时被释放?
假设我有一个方法,它调用上面的方法
void bar()
{
string testString = foo();
}
在上面的代码中,从foo()返回的字符串对象在什么时候调用其析构函数?它是在被复制到对象testString之后立即被复制的吗?
在您的示例中发生的情况是,具有签名的构造函数
string ( const char * s );
被调用。构造函数为字符串的副本分配新内存,并将其复制到该新内存中。字符串对象负责在调用其析构函数时释放自己的内存。
当您复制字符串时,复制构造函数还会分配内存并进行复制。
您还应该看看RAII模式。string
的内存管理就是这样工作的。
不,没有内存泄漏,您不需要做所有这些,这里相当于您的代码
string foo()
{
return "This is a test";
}
在此代码中:
char tempArray[30];
tempArray
是一个具有自动存储持续时间的变量。当tempArray
"超出范围"时,它会自动销毁。将此数组的内容(有些笨拙)复制到std::string
中,然后按值返回该string
。则CCD_ 7被破坏。它这里需要注意的是,tempArray
是数组。它不是指向数组第一个元素的指针(通常被误解),而是数组本身。由于tempArray
被破坏,因此阵列被破坏。
如果您使用具有动态存储持续时间的变量,例如:,则会发生泄漏
char* tempArray = new char[30];
strcpy(tempArray, "This is a test");
return string(tempArray);
注意没有匹配delete[]
的new[]
。这里,tempArray
是仍然一个具有自动存储持续时间的变量,但这次它是一个指针,它指向的东西具有动态存储持续时间。换句话说,当tempArray
超出作用域时,它会被销毁,但它只是一个指针。它指向的东西——char
数组本身,并没有被破坏,因为你没有delete[]
它
不是特别有效,但没有,没有泄漏。
不,它不会导致任何泄漏,因为您从不在堆上分配内存。如果使用malloc
、calloc
或new
。。而你从来没有free
/delete
。那么,是的,内存泄漏!
数组是静态分配的,因此它是在堆栈上创建的。strcpy
不返回动态分配的对象,它填充现有的数组,它知道如何做到这一点,因为你传入了指针,而不是在堆上分配的。返回字符串时,将生成字符串对象的副本。
您总是可以按值从函数返回局部自动变量。对于任何类型,这都应该是安全的(除非复制构造函数不安全):
T foo()
{
return T(...);
}
或:
T foo()
{
T t
return t;
}
你的例子与我的第一个案例相匹配。
不安全的是返回指向本地自动变量的指针/引用:
T& foo()
{
T t
return t;
}
T* foo()
{
T t
return &t;
}
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 我在二维向量中是否正确分配了内存
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 添加静态constexpr成员是否会更改结构/类的内存映射
- 是否值得降低我的代码的可读性,以便在出现内存不足错误时提供异常安全性?
- 使用 ImageIO.read() 生成的图像是否仍然使用传递给它的相同内存?
- 内存围栏是否涉及内核
- 我是否生成线程并导致内存泄漏?
- 公共/私有/受保护是否会更改内存中结构的排列?
- 是否可以通过每次在内存中仅保存一个平铺来处理完整的平铺 tiff 图像?
- 在没有动态内存的世界中,我是否需要虚拟析构函数?
- std::p romise::set_value() 和 std::future::wait() 是否提供内存围栏?
- 具有相同特征的两个对象是否只在内存中存储一次?无论定义它们的函数是什么,都是不同的
- 是否可以使用分配器对象来释放另一个分配器分配的内存?
- 释放动态分配的内存时是否需要执行此额外步骤
- 当另一个数组是内存集时,内存集是否会更改数组长度?
- 内存中类位置的成员是否取决于类成员在类定义中的位置?
- 是否可以仅通过将分配的指针地址存储在C++中来分析内存?
- 当新的故障时,是否有必要留出一些紧急内存?
- 如何检查链表是否内存不足/已满