This question already has answers here:
gets into char *str without malloc, no segfault?
                                
                                    (2个答案)
                                
                        
                                4年前关闭。
            
                    
在Red Hat Enterprise Linux Server 6.5(圣地亚哥)中
 与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;
}


问题是如何编写一个显示此问题的测试?

最佳答案

您正在定义一个指针而不初始化它。这意味着它具有未定义的值,即。它指向内存中的随机点。根据定义,写入此位置不会导致段错误,因为段错误意味着您写入(或读取)了您不拥有的位置。
但是由于您是在程序的最开始运行此程序的,因此仍然存在于堆栈中的指针(参见下文)仍有可能通过一些隐藏的初始化代码指向程序中的某个变量。但是如上所述,这是不确定的行为。它可能会导致段错误,可能会使您的程序在其他地方混乱……没人知道。



我所说的“仍在堆栈上”的意思是:如果您为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)相同。
在这种情况下,a是有效的内存(它是您的),但是它是偶然访问的。因此,它不会导致段错误。

关于c - 是否有测试将“未定义的行为”显示为错误,还是仅通过检查源代码即可? ,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/30545371/

10-12 01:23
查看更多