C++ c++;仅分配函数调用返回的结构的一部分
我有以下结构:C++ c++;仅分配函数调用返回的结构的一部分,c++,struct,heap-memory,assign,stack-memory,C++,Struct,Heap Memory,Assign,Stack Memory,我有以下结构: struct foo{ int a[4]; int b[4]; } 我有以下功能: foo get_foo() { foo ret_val; <..some assignments here..> return ret_val; } foo get_foo() { 福雷特瓦尔; 返回返回值; } 现在,我的主要代码是: void* process_a() { int* pa = get_foo().a; &
struct foo{
int a[4];
int b[4];
}
我有以下功能:
foo get_foo()
{
foo ret_val;
<..some assignments here..>
return ret_val;
}
foo get_foo()
{
福雷特瓦尔;
返回返回值;
}
现在,我的主要代码是:
void* process_a()
{
int* pa = get_foo().a;
<..do smth with "pa"..>
return pa;
}
void*进程_a()
{
int*pa=get_foo().a;
返回pa;
}
看起来代码运行得很好,但完全不知道完整的结构会发生什么,因为我只能访问它的子部分。
问题如下:
- 只将堆栈上创建的结构的一部分指定给指针可以吗
- foo结构在哪里?在堆栈上?还是堆李>
- 编译器是否足够聪明,可以只分配int[4](这是不太可能的),或者它将分配完整的foo
- 为我的爸爸活着的时间是什么时候?我能否在进程a()函数之外可靠地使用该指针李>
- 是的,可以将指针指定给结构的内部字段
在堆栈上foo
- 就像你说的,这不太可能
的生存期与任何局部变量的生存期一样-直到func结束。不能在func范围之外使用它。但是,这里有一个不同的问题-get_foo的返回值是临时的,一旦您超出分配给pa
的范围,它就可以被解除分配,因此此后对pa
所指数据的任何使用都将导致未定义的行为pa
- 是的,但它仅在结构的生命周期内有效
- 函数返回的结构是一个临时对象,它会立即被销毁。
将有一些空间,可能是“堆栈上”,供函数返回其结果。
一旦赋值的右侧被执行,结构就不会存储在任何地方,因为它不存在李> - 它几乎肯定会为整个结构分配空间李>
的生存期是pa
的主体,但是过程a
的生存期如上所述已经过期。*pa
因此,即使在
内部,也不能将process\u a
的值用于任何事情(复制它除外)pa
您的代码似乎运行良好,因为“似乎运行良好”是未定义行为的有效形式,与其他任何东西一样。可能的重复项甚至不能在
process\u a
内部使用pa
,因为它没有指向任何有意义的地方。即使在process\u a
函数内部,也不能使用pa
,因为一旦表达式pa=get\u foo().a
完成后,返回的结构将被破坏,留下一个散乱的指针。如果您需要a
文件,您应该复制它。记住:如果你只使用适当的C++类,那么在处理这种情况时就更容易了。如果结构在堆栈上,第一点就可以了,但它不是。get\u foo
返回的结构不存储在任何地方,因此它是临时的,将在表达式末尾不再存在。@JoachimPileborg嗯,返回值必须存储在某个地方,至少要存储到表达式末尾。据我所知,返回值的标准位置是堆栈。事实上,请看这里:也许编译器会将其存储在堆栈上,也许它会以某种方式对其进行优化,这是无从得知的。我们所知道的是,临时对象将被销毁,并且在赋值之后不再有效。存储指向已破坏对象或其成员的任何类型的指针都会导致灾难,并导致未定义的行为。@JoachimPileborg对此没有异议,我在第四个项目中明确提到了这一点。但我的第一个项目涉及将指针分配给返回值的内部字段的有效性。赋值本身是完全有效的。这将成为一个悬而未决的指针后,立即,但这是一个完全不同的问题