我最近在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(我知道我应得的)。你能解释为什么这段代码有效而不会出现分段错误吗?
我的输出如下所示:
答案 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*100
,s[0]
,但令人惊讶的是我的编译器没有给我任何警告或错误,它完美无缺。
时间降低您的期望,或提高编译器的诊断级别。如果它采用该样式的选项,请尝试s[1]
。它应警告您-Wall -Wextra
未经初始化而被使用。警告string
已被弃用也是一个好主意,尽管我的编译器没有提到它。
C和C ++允许您自己管理内存。您负责验证指针。在C中,这是问题的主要来源。
在C ++中,解决方案是使用指针的替代方法,例如引用(不能未初始化)和智能指针(为您管理内存)。虽然这个问题被标记为C ++并且编译为C ++程序,但它并不是用一种称为C ++的样式编写的。