malloc和scanf字符串
下面用malloc和scanf和%s得到一个字符串的简单程序如下所示,给出了一个我无法理解的输出。 虽然我’malloced’只有5个字节,但我的输入字符串已超过上述大小但没有分段错误。 scanf是否覆盖了malloc分配?
#include #include #include int main() { char * name; int SZSTRING; printf("Enter size of name :"); scanf("%d", &SZSTRING); name = (char*) malloc ((SZSTRING + 1) * sizeof(char)); printf("Enter name :"); scanf("%s", name); printf("len of 'name' : %d\n",strlen(name)); printf("name final: \"%s\"\n",name); free(name); return 0; } Output: OptiPlex-380:~/gsa/compile$ gcc -o try try.c OptiPlex-380:~/gsa/compile$ ./try Enter size of name :4 Enter name :qwertyui len of 'name' : 8 name final: "qwertyui"
我在这里注意到了另外一件事:
//scanf("%s", name);
输出显示
len of 'name'= 0
‘malloced’位置实际上是memset为NULL。 但是它的calloc而不是malloc根据man-page将分配的字节初始化为0 ???
它似乎“有效”,但那只是因为你很幸运。 当我在一个编译器上运行你的代码时,它在另一个编译器上“工作”,因为堆损坏而崩溃。 如果你想使用scanf()
你最好的选择是允许scanf()为你分配内存:
scanf("%ms", &name); // compiled with -std=c99 this will allocate the correct amount // of memory for you. You can use "%as" if you're using -std=c89
还要记住, scanf()
有一个返回值(它告诉你成功匹配和分配的输入项的数量),检查它是否有效是很重要的。
虽然我们处于良好实践中,但您不应该对malloc()
的返回值进行类型转换
另一种不使用scanf()
替代方法是使用fgets()
代替:
fgets( name, SZSTRING, stdin);
不,它没有。 但超过分配的缓冲区大小并不总是立即导致分段错误。 有时区域会被破坏,效果会在以后甚至从不显示。
这种情况可能会在没有segfault的情况下运行。 在这种情况下,它只是你正在使用一个你没有声称的空间,破坏了一些可能由“某人”拥有的内存位置。