在堆上创建变量并返回相同的变量
Creating variable on heap and return the same variable
嗨,我对堆变量几乎没有疑问...
我想写一个函数如下 ->
struct test
{
int x;
int y;
};
test* fun()
{
test *ptr = new test;
return ptr;
}
我的怀疑是返回一个堆变量,一旦它超出范围,它就会失去它的值。
肯定有内存泄漏。因为堆变量不会被删除。
那么我该如何设计这样的功能呢?
动态分配的对象(您称之为堆变量)不会在创建它们的作用域结束时被销毁。这就是动态分配的重点。当test
对象是动态分配的时,指针ptr
不是 - 当它超出范围时,它将被销毁。不过没关系!将指针的值从函数中复制出来,此副本仍指向test
对象。test
对象仍然存在。你写的函数很好,但它不是很好的风格。
是的,如果没有人在指向您创建的test
对象的指针上执行delete
,则存在内存泄漏。这是返回像这样的原始指针的问题。您必须信任调用方delete
您正在创建的对象:
void caller()
{
test* p = fun();
// Caller must remember to do this:
delete p;
}
一种常见的 C 样式方法(在 C++ 中绝对不推荐)是具有一对create_test
和destroy_test
函数。这仍然将相同的责任放在调用方身上:
void caller()
{
test* p = create_test();
// Caller must remember to do this:
destroy_test(p);
}
解决此问题的最佳方法是不使用动态分配。只需在堆栈上创建一个test
对象并将其复制(或移动)出函数:
test fun()
{
test t;
return t;
}
如果需要动态分配,则应使用智能指针。具体来说,unique_ptr
类型是您想要的:
std::unique_ptr<test> fun()
{
return std::unique_ptr<test>(new test());
}
然后,调用函数可以处理unique_ptr
,而不必担心对其执行delete
。当unique_ptr
超出范围时,它将自动delete
您创建的test
对象。但是,如果调用方希望其他函数具有该对象,则可以将其传递到其他地方。
-
您不是返回堆变量,而是返回包含指向堆的指针的堆栈变量的值。堆栈变量超出范围;指针指向的内存在堆中 - 它永远不会超出范围。
-
除非释放调用方中的内存,否则将出现内存泄漏。
我的怀疑是,一旦返回堆变量超出范围,它就会失去它的值。
不用担心,因为由于您是按值重新设置指针;因此指针将超出范围,但由于您返回的是它指向的内存,因此没有内存泄漏(仅当我们可以依靠调用方删除它时)。
但是,如果我们通过引用返回指针,那么我们就会遇到问题:
test*& fun() // note the & (reference)
{
test *ptr = new test;
return ptr;
}
在这里,你将返回对临时的引用。当变量超出范围时,您将使用不存在的对象。这就是无法通过引用返回临时的原因。
我的怀疑是返回一个堆变量,一旦它超出范围,它就会失去它的值。
没有堆变量不会像堆栈变量那样超出范围......
是的,肯定有内存泄漏。(因为堆变量不会被删除。
我们必须自己释放堆上分配的内存,否则会出现内存泄漏......
我建议阅读一些与之相关的教程。
- 你能重载对象变量名本身返回的内容吗
- 如何在 c++ 中让布尔变量返回为 0 或 1 而不是真或假?
- 从私有成员变量的成员方法返回unique_ptr
- 为什么我不能在返回 const 的布尔函数中为类成员变量赋值?C++
- C++ 根据给定的类型名从变量返回数据
- 为什么 std::isnan() 对于具有 NAN 值的双变量返回 false
- C++ 在静态函数中使用非静态变量返回类实例
- 具有变量返回类型的函数
- 带有 QVariant 和模板的变量返回类型
- getenv() 在不同的程序中为同一环境变量返回不同的值
- C 多重继承,虚拟方法覆盖问题和协变量返回类型
- 变量返回类型
- C++函数向字符串变量返回int
- 从临时变量返回的引用是否有效
- 有没有一种方法可以将C++数据类型作为变量返回
- 类函数的模板变量返回类型
- C++函数,使用'auto'变量返回类型
- 如何将引用变量返回到函数中
- 变量返回类型上转换覆盖c++
- 数组变量返回意外值