为什么当我溢出分配的字符数组时,我的C程序不会崩溃?

iro*_*ion 2 c memory arrays stack

我有一个简单的C文件I/O程序,它演示了逐行读取文本文件,并将其内容输出到控制台:

/**
* simple C program demonstrating how
* to read an entire text file
*/

#include <stdio.h>
#include <stdlib.h>

#define FILENAME "ohai.txt"

int main(void)
{
    // open a file for reading
    FILE* fp = fopen(FILENAME, "r");

    // check for successful open
    if(fp == NULL)
    {
        printf("couldn't open %s\n", FILENAME);
        return 1;
    }

    // size of each line
    char output[256];

    // read from the file
    while(fgets(output, sizeof(output), fp) != NULL)
        printf("%s", output);

    // report the error if we didn't reach the end of file
    if(!feof(fp))
    {
        printf("Couldn't read entire file\n");
        fclose(fp);
        return 1;
    }

    // close the file
    fclose(fp);
    return 0;
   }
Run Code Online (Sandbox Code Playgroud)

看起来我已经为每行分配了一个空间为256个字符的数组(32位机器上的1024 字节位).即使我ohai.txt在第一行填写超过1000个字符的文本,程序也不会出现段错误,我认为它会溢出,因为它溢出了output[]数组指定的可用空间.

我的假设是操作系统会为程序提供额外的内存,同时它有额外的内存可用.这意味着只有当一行文本占用的内存ohai.txt导致堆栈溢出时,程序才会崩溃.

有更多C和内存管理经验的人是否支持或反驳我的假设,即为什么这个程序不会崩溃,即使文本文件的一行中的字符数远大于256?

nne*_*neo 6

你不会在这里溢出任何东西:fgets不会sizeof(output)在缓冲区中写入多个字符,因此不会溢出任何内容(参见文档).

但是,如果溢出缓冲区,则会出现未定义的行为.根据C规范,程序可以做任何事情:崩溃,不崩溃,无声地破坏重要数据,意外调用rm -rf /等等.因此,如果调用UB,不要指望程序崩溃.