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()函数之外可靠地使用该指针
谢谢! Igor.

  • 是的,可以将指针指定给结构的内部字段
  • foo
    在堆栈上
  • 就像你说的,这不太可能
  • pa
    的生存期与任何局部变量的生存期一样-直到func结束。不能在func范围之外使用它。但是,这里有一个不同的问题-get_foo的返回值是临时的,一旦您超出分配给
    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对此没有异议,我在第四个项目中明确提到了这一点。但我的第一个项目涉及将指针分配给返回值的内部字段的有效性。赋值本身是完全有效的。这将成为一个悬而未决的指针后,立即,但这是一个完全不同的问题