"printf" 会阻止数组的重新分配吗?

Does "printf" prevent deallocation of array?

当我发现我的输出取决于我是否包含对printf:

#include <stdio.h>

class Foo {
  public:
    double* array;

    Foo(void) {
        array = new double[16];
        for (int i = 0; i < 16; ++i)
            array[i] = 5+i;
    }

    ~Foo() {
        delete[] array;
    }
};

void Bar(double** ptr) {
    Foo f;
    *ptr = f.array;

    // Expression in question:
    printf("ptr = %p\n", *ptr);
}

int main(int argc, char* argv[]) {
    double* ptr = NULL;
    Bar(&ptr);    
    printf("ptr[3] = %4.1f\n", ptr[3]);
    return 0;
}

即,如果我在表达式 printf("ptr = %p\n", *ptr); 中保留,则输出为

ptr = 0x7fd7f44058d0

ptr[3] = 8.0

但是如果我注释掉那个表达式,那么输出就是

ptr[3] = 0.0

看来 printf 正在以某种方式在幕后管理内存?

(我知道无论如何我都不应该偷看 ptr[3],但我只是好奇为什么会发生这种情况。)

编辑:是的,即使不追求未定义的行为,代码也不会很好;这里的目标不是解决或预防问题,只是了解问题发生的原因。 我认为我的问题的答案只是编译器正在做一些有用的事情,并且根据 printf 是否存在

它会得到不同的想法

查看您正在创建的对象的生命周期。

Foo f;

这存在于 Bar() 的范围内,但是当 Bar() 退出时,f 被销毁,释放您创建的缓冲区。

此时,ptr 指向一些随机的内存位置,可以用于其他任何事情。你不能再指望它了。你不知道那里会发生什么。

这是一个彻头彻尾的错误。

在那里调用 printf 可能会使编译器重新排列内容,因此它们与未调用它时不同,并且该值可能会在该内存地址中保留一段时间,但您不能 (而且你不应该)指望那个。

正如评论和@Joseph Larson 所说,您的构造是一个错误。