C - Malloc 和 scanf 字符串



下面的一个简单的程序,带有 malloc 和 scanf 和 %s 来获取如下字符串,给了我一个我无法理解的输出。虽然我只"错误定位"了 5 个字节,但我的输入字符串超过了上述大小,但没有分段错误。scanf 是否覆盖了 malloc 分配?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
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' : %dn",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

和"错误定位"位置实际上被内存设置为 NULL。但是它的 calloc 而不是 malloc,它根据手册页将分配的字节初始化为 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);
不,

它没有。但是,超过分配的缓冲区大小并不总是立即导致分段错误。有时区域会损坏,效果会在以后甚至永远不会显示。

这种情况可能会在没有段错误的情况下运行。在这种情况下,只是您正在使用一个您尚未声明的空间,从而损坏了一些可能由"某人"拥有的内存位置。

最新更新