Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/65.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 未初始化的值是由堆分配创建的,如果我没有';t do memset_C_Malloc_Valgrind_Memset - Fatal编程技术网

C 未初始化的值是由堆分配创建的,如果我没有';t do memset

C 未初始化的值是由堆分配创建的,如果我没有';t do memset,c,malloc,valgrind,memset,C,Malloc,Valgrind,Memset,我感兴趣的是这个 char *assign_value = (char*)malloc(10 * sizeof(char)); if(strlen(assign_value) == 0) { strcpy(assign_value, "A"); } else { strcat(assign_value, "A"); } 基本上,在上面的示例中,我将得到一个错误,即未初始化的值是由堆分配创建的。但若我执行以下操作并在malloc()和if语句之间插入memset(),我就不会看到

我感兴趣的是这个

char *assign_value = (char*)malloc(10 * sizeof(char));
if(strlen(assign_value) == 0) {
    strcpy(assign_value, "A");
} else {
    strcat(assign_value, "A");
}
基本上,在上面的示例中,我将得到一个错误,即未初始化的值是由堆分配创建的。但若我执行以下操作并在malloc()和if语句之间插入memset(),我就不会看到相同的错误。我想听听一些建议,这是正确的方式吗?如果不是,什么是正确的做法

char *assign_value = (char*)malloc(10 * sizeof(char));
memset(assign_value, 0, sizeof(assign_value));
if(strlen(assign_value) == 0) {
    strcpy(assign_value, "A");
} else {
    strcat(assign_value, "A");
}

谢谢

是的,从
malloc
返回的内存未初始化。通常,它将包含不可预测的随机值。偶然的情况下,随机值可能是0——但你根本不能指望这一点

因此,是的,如果您愿意,您必须始终初始化从
malloc
返回的内存。一种方法是调用
memset
——尽管您发布的示例并不常见。如果你想把刚回来的所有内存归零,通常的方法是

memset(assign_value, 0, 10);
(除了
malloc
,您还可以使用
calloc
malloc
calloc
之间的一个区别是
calloc
会自动将新分配的内存初始化为所有0。)

如果将
赋值作为字符串使用,并且希望它以空字符串开头,则不必全部归零。只需在第一个位置放置空字符即可:

*assign_value = '\0';
一旦您执行这些操作,
assign\u value
将保存一个长度为0的空字符串。因此,您的测试
if(strlen(assign_value)==0)
将始终成功,并且在以后的代码中,您将始终调用
strcpy
,而不是
strcat

最后,作为补充,在调用
malloc
时,您不必乘以
sizeof(char)
,也不必强制转换结果。因此,您可以使用更简单的:

char *assign_value = malloc(10);

(您不必乘以
sizeof(char)
,因为
sizeof(char)
根据定义总是正好1。您不必在C中显式强制转换
malloc
的结果,如果这样做,它可以隐藏错误。)

问题来自调用
strlen(赋值)
assign\u value
未初始化时,由
malloc(10)
返回

以下是解决此问题的三种方法:

  • 您可以使用
    memset手动设置数组的所有字节(赋值,0,10)。请注意,您的调用不正确,因为
    sizeof(assign\u value)
    的计算结果是指针的大小,而不是数组的大小

  • 您可以使用
    calloc(10,sizeof(char))
    分配数组
    calloc
    返回初始化为所有零位的内存块的地址,其效果与调用
    memset
    相同,但可能更有效

  • 您可以将初始字节设置为
    '\0'
    ,使数组成为空字符串,可与
    strcpy
    strcat
    一起使用

使用
calloc()
而不是
malloc()
是一个好习惯,可以避免在使用前未能初始化任何或所有分配的数据时出现不可预知的行为

请注意,您的代码可以从根本上简化:如果目标字符串确实为空,则调用
strcat()
相当于
strcpy()
。你可以写:

char *assign_value = calloc(10, sizeof(char));
...
strcat(assign_value, "A");
此外,您应该通过检查已存储在缓冲区中的字符串的长度来验证
strcat()
不会导致缓冲区溢出:

char *assign_value = calloc(10, sizeof(char));
...
if (strlen(assign_value) < 10 - 1) {
    strcat(assign_value, "A");
} else {
    // handle the error: not enough space in assign_value
}
char *assign_value;
assign_value = malloc(10 * sizeof(char));
memset(assign_value, 0, 10);
char*assign_value=calloc(10,sizeof(char));
...
if(strlen(赋值)<10-1){
strcat(赋值为“A”);
}否则{
//处理错误:赋值中没有足够的空间
}
malloc()
分配内存,但不初始化内存。无论在分配的内存位置中发生什么,都是您得到的。
因此,在使用
malloc
时,最好创建并初始化缓冲区:

char *assign_value = calloc(10, sizeof(char));
...
if (strlen(assign_value) < 10 - 1) {
    strcat(assign_value, "A");
} else {
    // handle the error: not enough space in assign_value
}
char *assign_value;
assign_value = malloc(10 * sizeof(char));
memset(assign_value, 0, 10);
另一方面,
calloc()
分配内存并初始化分配给0的所有位置:

char *assign_value = calloc (10,1);//note sizeof(char) is always 1
更多阅读,这里有一个讨论


注意,不必在[c]中将[[M] [C]异类的输出转换成C++。

<代码> Malc 绝对不要初始化或将其零化。如果你愿意,你可以在它之后使用
memset
,或者使用
calloc
。谢谢你的回答,我今天学到了一些新东西。很好