即使我没有为其分配内存,为什么还能正常工作?

时间:2015-06-21 06:26:38

标签: c++ c segmentation-fault gets

我最近在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],.......但令人惊讶的是我的编译器没有给出我有任何警告或错误,它完美无缺。

所以我发布了这段代码,并且坦率地得到了相当多的downvotes(我知道我应得的)。你能解释为什么这段代码有效而不会出现分段错误吗?

我的输出如下所示:

Output

1 个答案:

答案 0 :(得分:3)

      RichTable table = (RichTable)FacesContext.getCurrentInstance().getViewRoot().findComponent("pt1:t1");
          if(null!=table.getSelectedRowKeys())

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

char

嗯,这会从标准输入读取数据,从随机地址开始加上gets(string[i]); ,直到读取NUL字节为止。

不太健壮。也不保证会产生错误。如果没有得到,则随机地址必须已映射到可写字节。

  

如您所见,我没有为单个字符串分配任何内存,即i*100s[0],但令人惊讶的是我的编译器没有给我任何警告或错误,它完美无缺。

时间降低您的期望,或提高编译器的诊断级别。如果它采用该样式的选项,请尝试s[1]。它应警告您-Wall -Wextra未经初始化而被使用。警告string已被弃用也是一个好主意,尽管我的编译器没有提到它。

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

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