gpt4 book ai didi

c++ - c++中抛出的对象在哪里?

转载 作者:可可西里 更新时间:2023-11-01 18:29:40 25 4
gpt4 key购买 nike

我想弄清楚我抛出的对象在内存中的存储位置。所以我为它写了一个小程序:

#include <iostream>

#define print_dist() int a;\
do { std::cout << __FUNCTION__ << "() a[" << (long)&a - (long)ptrMainStackBase << "]" << std::endl; } while (0)

#define print_distx(x) \
do { std::cout << __FUNCTION__ << "() " #x "[" << (long)&x - (long)ptrMainStackBase << "]" << std::endl; } while (0)

#define print_distxy(x, y) \
do { std::cout << __FUNCTION__ << "() " #x "(ex)[" << (long)&x - (long)y << "]" << std::endl; } while (0)

class CTest
{
public:
CTest()
{ std::cout << "CTest::CTest" << std::endl; }

// private:
CTest(const CTest&)
{ std::cout << "copy" << std::endl; }
};
const CTest *ptrException;
int *ptrMainStackBase;

void Test2()
{
print_dist();
CTest test;
print_distx(test);
std::cout << "&test=" << &test << std::endl;
throw test;
}

void Test1()
{
print_dist();
try
{
Test2();
}
catch (const CTest& test)
{
ptrException = &test;
print_dist();
print_distx(test);
print_distxy(test, ptrException);
std::cout << "&test=" << &test << std::endl;
throw test;
}
}

int main()
{
int b;
ptrMainStackBase = &b;
print_dist();
try
{
print_dist();
Test1();
}
catch (const CTest& test)
{
print_dist();
print_distx(test);
print_distxy(test, ptrException);
std::cout << "&test=" << &test << std::endl;
}

return 0;
}

并打印:

main() a[-4]
main() a[-8]
Test1() a[-64]
Test2() a[-104]
CTest::CTest
Test2() test[-108]
&test=0x7fffd3b21628 <- test created here on stack
copy
Test1() a[-68]
Test1() test[-140736732956164]
Test1() test(ex)[0]
&test=0xb89090 <- and copied here
copy
main() a[-12]
main() test[-140736732956020]
main() test(ex)[144]
&test=0xb89120 <- and here

看起来,当我抛出一个对象时,它首先被复制到另一个远离正常对象的堆栈。这是真的?为什么两个“异常堆栈帧”之间有144字节的距离?

最佳答案

当你抛出一个对象时,它确实首先被复制到某个临时位置。否则,堆栈展开将超出范围。然后通过引用捕获它会导致未定义的行为,如下所示:

void foo() {
A a;
throw a;
}

void bar() {
try {
foo();
} catch (A& a) {
// use a
}
}

除非 a 已被复制到某个临时位置,否则您将引用一个不再存在于 catch 中的变量。为此,A 必须具有公共(public)复制构造函数(除非您使用的是 VS,在这种情况下 it will use a private one as well... )。此外,这是通过引用捕获的一个很好的理由 - 否则,您将拥有两个复制结构而不是一个。

关于c++ - c++中抛出的对象在哪里?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11281837/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com