malloc和scanf字符串

malloc和scanf字符串,c,string,malloc,scanf,C,String,Malloc,Scanf,下面是一个简单的程序,它使用malloc和scanf以及%s获得如下字符串,给了我一个无法理解的输出。虽然“malloced”只有5个字节,但我的输入字符串已超过上述大小,但没有分段错误。 scanf是否超出了malloc分配 #include <stdio.h> #include <stdlib.h> #include <string.h> int main() { char * name; int SZSTRING; printf("E

下面是一个简单的程序,它使用malloc和scanf以及%s获得如下字符串,给了我一个无法理解的输出。虽然“malloced”只有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"
输出显示

len of 'name'= 0

“malloced”位置实际上被memset设置为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()的替代方法是使用:

这可能看起来“有效”,但那只是因为你运气好。当我在一个编译器上运行代码时,它会在另一个编译器上“工作”,因为堆损坏而崩溃。如果要使用
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()的替代方法是使用:


这样的案例很可能在没有故障的情况下运行。在这种情况下,您只是使用了一个尚未声明的空间,损坏了一些可能属于“其他人”的内存位置。

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

这是未定义的行为,任何事情都可能发生。它甚至可以“工作”。这是未定义的行为,任何事情都可能发生。它甚至可以“工作”。所以我理解,我必须手动跟踪最终字符串的大小。也许循环中的getchar是一个值得信任的选择?@Aad,您可以使用
fgets()
并指定要读取的最大字符数。因此,我理解,我必须手动跟踪最终字符串的大小。也许循环中的getchar是一个值得信任的选择?@Aad,您可以使用
fgets()
并指定要读取的最大字符数。这不应该是
&name
?当我使用
name
@mhutter时,我会遇到一些错误——事实上,当我键入答案时,它应该是错过了。这是三年来第一个发现这种情况的人那不应该是
&name
?当我使用
name
@mhutter时,我会遇到一些错误——事实上,当我键入答案时,它应该是错过了。这是三年来第一个发现这种情况的人
fgets( name, SZSTRING, stdin);