C++ 指针和文字常量
我有一个不应该工作的代码,但它可以工作。你能告诉我为什么吗C++ 指针和文字常量,c++,pointers,literals,C++,Pointers,Literals,我有一个不应该工作的代码,但它可以工作。你能告诉我为什么吗 #include <iostream> void f ( int** a, int b ) ; int main (void) { int ** a ; a = new int* () ; f(a,5) ; std::cout << **a << std::endl ; return 1 ; } void f ( int** a, int b
#include <iostream>
void f ( int** a, int b ) ;
int main (void) {
int ** a ;
a = new int* () ;
f(a,5) ;
std::cout << **a << std::endl ;
return 1 ;
}
void f ( int** a, int b ) {
*a = &b ;
}
#包括
无效f(整数**a,整数b);
内部主(空){
国际**a;
a=新整数*();
f(a,5);
std::cout它似乎有效,但实际上不起作用
*指向堆栈上地址的点
打印**a时,实际打印的是堆栈上某个地址的内容。(调用函数f时包含5的地址)
但是,由于堆栈不会根据代码发生太大变化,因此值5仍然写入特定地址,因此会打印值5。
如果您调用其他函数,然后打印**a,您可能会得到不同的值。它似乎可以工作,但实际上不能
*指向堆栈上地址的点
打印**a时,实际打印的是堆栈上某个地址的内容。(调用函数f时包含5的地址)
但是,由于堆栈不会根据代码发生太大变化,因此值5仍然写入特定地址,因此会打印值5。
如果您调用其他函数,然后打印**a,您可能会得到不同的值。在您的情况下,内存不会立即被覆盖。这是未定义的行为,并且可能不会一直保持相同的行为。每个编译器可能会对其进行不同的处理,您可能会在不同的平台上,甚至在版本vs中看到不同的结果调试模式。在您的情况下,内存不会立即被覆盖。这是未定义的行为,并且可能不会一直保持相同的行为。每个编译器可能会对其进行不同的处理,您可能会在不同的平台上看到不同的结果,甚至在版本与调试模式中看到不同的结果。它调用未定义的行为,而未定义的行为是未定义的。当他们说这是一个未定义的行为时,这意味着它可以通过正确的行为或有时不起作用来让你彻底崩溃。它不起作用;它有未定义的行为。当你销毁它所包含的对象时,内存不一定会消失,所以悬空指针可能(也可能不会)仍然可以看到以前的值。如果启用它们,您应该会收到编译器警告。@MikeSeymour我正在使用-Wall-pedantic编译,编译器不会抱怨。我应该使用哪些标志。@GonzoRI:实际上,也许您不会收到警告。大多数流行的编译器会诊断返回&b;
,但可能是因为对*a
的签名超出了编译器的分析能力。它调用未定义的行为,而未定义的行为是未定义的。当他们说它是未定义的行为时,这意味着它可以通过正确的行为或有时它不起作用来让你感到非常痛苦。它不起作用;它有未定义的行为。内存不一定会被破坏销毁它包含的对象时出现,因此悬空指针可能会(也可能不会)出现仍然可以看到以前的值。如果启用它们,您应该会收到编译器警告。@MikeSeymour我正在使用-Wall-pedantic编译,编译器不会抱怨。我应该使用哪些标志。@GonzoRI:实际上,也许您不会收到警告。大多数流行的编译器会诊断返回&b;
,但可能是因为对*a
的签名超出了编译器的分析能力。