为什么即使我没有为它分配内存,它也会工作?
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++ 的风格编写的。
我最近在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++ 的风格编写的。