当我看到以下警告时,这个问题突然出现在我的脑海中。
struct Wrapper{
char somechar[10];
};
auto returnFoo() {
char somechar[10];
return somechar; // Warning: address of stack memory returned!
}
auto returnFoo() {
Wrapper wpr;
return wpr; // OK
}
我理解警告。但是我不明白为什么当我使用包装器时它会消失。我猜编译器可以计算出类有多大并复制正确数量的字节,但不能对指针(char [])做同样的事情?
类的“大小”存储在哪里(我猜不在堆栈中,因为那会很浪费,也许在数据段中?)
编辑:
我想我的问题用错了,我知道
sizeof
并有一些CPP的经验。我知道 char[] 会衰减为 char*。而且我知道第一个示例返回一个指针,第二个示例返回一个对象。我要问的是编译器的内部是如何工作的。
对于编译器,内存布局完全相同(给予或接受),它需要做的是复制数组并将其返回。它需要知道要复制多少字节。我的问题是,为什么它能够在使用对象时弄清楚,而不是使用 char[]
最佳答案
函数不能在 C++ 中返回数组。这就是指定语言的简单方式。这在 C 中也是一样的。
在第一个示例中,数组名称衰减为指向数组第一个元素的指针,推导出的返回类型是指向 char 的指针。指针可以返回,但是指针会失效,因为函数返回时指向对象的自动存储已经被释放。
I don't get why it goes away when I use the wrapper.
使用包装器时,不会返回指针。您返回本地类实例的拷贝。数组存储在类中。
I guess the compiler can figure out how big the class is
编译器知道类是如何定义的,因此它知道大小。您可以使用
sizeof(Wrapper)
找出编译器自己了解的内容。 .Where is the "Size" of the class stored
取决于语言实现。在典型情况下,编译器会为 CPU 生成诸如“将堆栈指针递增 10”的指令,因为编译器知道大小为 10。它知道大小是因为它知道定义。
Where is this definition stored (the symbol table, the data segment, the stack, the text segement)?
这些都没有。您已将定义存储在源文件中。编译器将解析它并将信息以某种内部表示形式存储在编译器进程的内存中。
为 CPU 生成指令的是编译器,因此只有编译器需要知道大小。生成的程序不生成指令(C++ 语言无法进行自我修改),因此不需要了解类型定义。
关于c++ - 从函数重新调整对象时,C++ 如何知道要复制多少字节?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63798645/