堆栈展开后的指针有效性
Pointer validity after stack unwinding
在c++中,堆栈展开后指针是否仍然有效?
这取决于指向对象的存储。如果该对象是堆栈分配的,那么指针肯定是无效的——堆栈展开将正确地销毁该对象。如果对象是堆分配的,只有当在堆栈展开期间有一些RAII变量释放对象时,指针才会失效。
这取决于你的指针指向什么。如果它指向堆内存,它仍然有效。如果它指向堆栈内存,它就无效。
No。通过堆栈展开,在堆栈未损坏部分的作用域中声明的所有变量/指针将被销毁。
此外,该规则还考虑了变量的Storage Type
。static
变量在函数调用之间保持其值,这意味着它在堆栈展开期间不会被销毁。这是因为静态变量不是存储在堆栈中,而是存储在BSS或数据段中。
Local variables
(Auto storage type
)总是在函数返回和堆栈展开时被销毁。
在堆上分配内存的指针在堆栈展开时不会被销毁,因为它们是在堆上而不是堆栈上分配的。
要记住的一个重要规则是永远不要返回指向函数内部局部变量的指针或引用。指针或引用将包含垃圾值。考虑一些例子:
void* f1a()
{
void* p = malloc(10);
return p;
}
…
void* f1b()
{
return malloc(10);
}
这很好,因为指针指向堆,因此独立于堆栈、函数调用和编程作用域。在函数返回时复制指针值。
int* f2()
{
int x;
return &x; // pointer to x - about to become invalid!
}
上面的函数返回一个指向堆栈上的变量x
的指针,当函数返回时,该指针将被回收(x
丢失)。
再说明一件我觉得很重要的事
说我们有这个语句
obj* objptr = new obj(9) //allocate memory on heap and use constructor
if here exception发生…内存堆被释放回....没有内存泄漏…
原因是....不是因为堆栈展开…而是因为new操作符转换为下面生成的代码的方式try catch语句在new operator中实现…像这样…
void * operator new(size_t s)
{
try
{
void * ptr=new(malloc (s))sample(); //placement new
ptr->...
}
catch(..)
{
operator delete(ptr); //<= notice here so if an exception occur then first it is caught here which releases the memory
}
}
然而,如果在对象内做了一些内存分配,仍然没有被释放。
相关文章:
- 1d 智能指针不适用于语法 (*)++
- 在C#中处理C++指针而不使用unsafe的最佳方法
- 为什么使用 "this" 指针调用派生成员函数?
- 函数向量_指针有不同的原型,我可以构建一个吗
- 使用指针从C++中的数组中获取最大值
- 助记符和指向成员语法的指针
- 嵌入方指针压缩已禁用
- 数组的指针从不分段故障
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- 何时在引用或唯一指针上使用移动语义
- 如何检查类中共享指针的有效性?
- 运算符返回的指针的有效性 >
- 我是否必须检查此方法的指针有效性
- 智能指针列表-管理对象生存期和指针有效性
- 测试C++对象的有效性,就好像它是一个指针一样
- std::d eque 会保留其包含对象的指针有效性吗?
- 移动std::set后指针的有效性
- 当派生指针仅添加方法时,将基指针强制转换为派生指针的有效性
- 从未知指针到类的强制转换;如何检查有效性
- 堆栈展开后的指针有效性