与gcc版本4.4.7以及 红帽企业Linux服务器版本5.8(Tikanga) 使用gcc 4.1.2版我们可以写:
#include <stdio.h>
int main( int argc, char *argv[] )
{
char * A;
char * B=A;
*B='C'; //run without segfalut
*++B='\0';
puts(--B);//print 'C' as well
return 0;
}
问题是为什么不出现segfalut问题?
答案 0 :(得分:2)
您正在定义指针而不进行初始化。这意味着它具有一个未定义的值,即。它指向内存中的随机点。根据定义,写入此位置不会导致段错误,因为段错误意味着您将(或读取)写入(或读取)非您拥有的位置。 但是,既然你在程序的最开始运行它,那么仍然在你的堆栈上的指针(见下文)仍有可能通过一些隐藏的初始化代码指向程序中的某个变量。但如上所述,它是未定义的行为。它可能会引起一个段错误,它可能只是把你的程序搞砸到其他地方......没人知道。
我的意思是&#39;仍然在堆栈上&#39;是这样的:如果你为一个int分配内存,这是通过将它放在堆栈上来完成的。现在堆栈略高,你的变量位于顶部。 现在,如果你分配一个变量(一个指针也只是一个变量,但包含一个地址),然后解除分配它,然后分配另一个变量,第二个变量的初始值与第一个变量相同。 (这也是未定义的,所以不要认为它是真的)。 假设我们有代码:
#include <stdio.h>
char a= 'A';
void one()
{
char* p1 = &a;
printf("char is '%c', addr = 0x%x\n", *p1, p1);
}
void two()
{
char* p2;
printf("char is '%c', addr = 0x%x\n", *p2, p2);
}
int main(int argc, char** argv){
one();
two();
}
很有可能会打印char is 'A'
两次。因为p2指向的恰好与p1相同,这是一个。
在这种情况下,a是有效的内存(它是你的),但它是偶然访问的。所以它不会导致段错误。