0

下面的一个简单程序使用 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' : %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

并且“分配”的位置实际上被 memset 为 NULL。但是它的 calloc 而不是 malloc 根据手册页将分配的字节初始化为 0???

4

3 回答 3

2

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

于 2013-01-24T12:14:02.393 回答
2

它可能看起来“有效”,但这只是因为你很幸运。当我在一个编译器上运行您的代码时,它在另一个编译器上“工作”,它由于堆损坏而崩溃。如果要使用,最好的选择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);
于 2013-01-24T12:22:12.140 回答
1

这种情况可能会在没有段错误的情况下运行。在这种情况下,只是您使用了一个您尚未声明的空间,破坏了一些可能由“其他人”拥有的内存位置。

于 2013-01-24T12:26:34.477 回答