为什么即使我没有为它分配内存,它也会工作?

Why does gets work even when I have not allocated memory to it?

我最近在SO这里回答了一个问题,问题是输入几句代码并打印出来。我的代码是这样的:

#include<stdio.h>  

int main() {
    clrscr();
    int line, i;

    char (*string)[100];
    printf("How many line?\n");
    scanf("%d",&line);
    getchar();

    for(i=0;i<line;i++) {
        gets(string[i]);
    }

    printf("You entered:\n");
    for(i=0;i<line;i++) {
        puts(string[i]);
    }

    return 0;
}

如您所见,我没有为单个字符串分配任何内存,即 s[0],s[1] ,....... 但令人惊讶的是我的编译器没有给我任何内存它的警告或错误,它工作得很好。

所以我发布了这段代码,坦率地说,它得到了很多反对票(我知道我活该)。你能解释一下为什么这段代码有效并且没有给出分段错误吗?

我的输出如图:

char (*string)[100];

OK,string表示指向100的指针char,但是没有初始化。因此,它代表一个任意地址。 (更糟糕的是,在随后的场合访问时,它甚至不一定代表相同的任意地址。)

gets(string[i]);

嗯,这会将数据从标准输入读取到从随机地址开始的内存块,加上 i*100,直到读取 NUL 字节。

不是很健壮。也不保证会产生错误。如果你没有得到一个,随机地址一定已经映射到可写字节。

As you see, I haven't allocated any memory to individual strings i.e, s[0],s[1] but surprisingly my compiler didn't give me any warnings or errors for it and it works perfectly.

是时候降低您的期望值,或提高编译器的诊断级别了。尝试 -Wall -Wextra,如果它采用那种风格的选项。应该警告您 string 未先初始化就被使用。 gets 已被弃用的警告也是一个好主意,尽管我的编译器没有提及它。

C 和 C++ 允许您自己管理内存。您负责验证指针。在 C 中,这是问题的主要来源。

在 C++ 中,解决方案是使用指针的替代方法,例如引用(不能取消初始化)和智能指针(为您管理内存)。虽然问题被标记为 C++ 并编译为 C++ 程序,但它不是以称为 C++ 的风格编写的。