C程序只有在GCC中执行后才终止

C程序只有在GCC中执行后才终止,c,gcc,compiler-construction,C,Gcc,Compiler Construction,我有意在我的程序中进行越界索引访问,如下所示: #include<stdio.h> int main() { int x[1]; x[1] = 3; // expected SIGABRT here printf("x[1] = %d\n",x[1]); return 0; } #包括 int main() { int x[1]; x[1]=3;//此处应为SIGABRT printf(“x[1]=%d\n”,x[1]); 返回0; } 但是

我有意在我的程序中进行越界索引访问,如下所示:

#include<stdio.h>

int main()
{
    int x[1];

    x[1] = 3; // expected SIGABRT here
    printf("x[1] = %d\n",x[1]);

    return 0;
}
#包括
int main()
{
int x[1];
x[1]=3;//此处应为SIGABRT
printf(“x[1]=%d\n”,x[1]);
返回0;
}
但是我的程序只是在执行了我期望中止的那一行之后才被终止。我调试时也发生了同样的情况。找到下面的输出

x[1] = 3
*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)
x[1]=3
***检测到堆栈崩溃***:已终止
中止(堆芯转储)

我知道C没有越界检查功能。我的问题是,为什么它在执行x[1]=3之后没有终止而不执行下一条语句?

我假设这是关于使用金丝雀值来检测利用堆栈缓冲区溢出的尝试

直到函数返回,才会检查堆栈(也称为金丝雀值)。因此,您将首先执行
printf
,然后执行堆栈检查

换句话说,“越界”访问在发生时不会被检测到。因此,程序将继续运行,直到函数返回

您可以将有问题的代码放入如下函数:

void foo()
{
    int x[1];

    x[1] = 3; // expected SIGABRT here
    printf("x[1] = %d\n",x[1]);
}

int main()
{
    foo();
    printf("Back in main\n");
    return 0;
}

要查看程序是否在打印“Back in main”之前终止,C是一种本机语言,允许您访问其边界之外的数组而无需检查。但它会导致未定义的行为。@LM358为什么在程序执行后我会被中止?为什么在程序执行后不能?没有人强迫程序崩溃。没有人强迫它不崩溃。你调用了未定义的行为;这意味着没有可靠的方法来预测会发生什么结果。当
main()
的返回代码检查堆栈并发现堆栈崩溃时,可能会发生崩溃。替换
返回0
退出(0)
(当然还有
#include
),您可能根本不会收到任何错误,或者您可能仍然会被发现;这就是未定义行为的美妙之处。任何事情都可能发生,这是正常的-未定义的行为。我知道C没有越界检查功能。我的问题是,为什么它没有[提前]终止?这个问题似乎与前面的陈述不一致。