"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 所说,您的构造是一个错误。
当我发现我的输出取决于我是否包含对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 所说,您的构造是一个错误。