我感兴趣的是这个。
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");
}
谢谢!
问题来自于在assign_value
未初始化时调用strlen(assign_value)
,由malloc(10)
返回。
以下是修复问题的三种方法:
-
您可以使用
memset(assign_value, 0, 10);
手动设置数组的所有字节。请注意,您的调用是不正确的,因为sizeof(assign_value)
计算的是指针的大小,而不是数组的大小。 -
您可以使用
calloc(10, sizeof(char))
来分配阵列。calloc
返回初始化为所有零位的存储器块的地址,这与调用memset
具有相同的效果,但可能更高效。 -
您可以将初始字节设置为
' '
,使数组成为空字符串,对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
}
是的,您从malloc
返回的内存未初始化。通常,它将包含不可预测的随机值。偶然的情况下,的随机值可能为0,但你根本无法指望这一点。
所以,是的,如果你关心的话,你必须总是初始化你从malloc
中得到的内存。一种方法是调用memset
——尽管您发布的示例并不常见。如果你想把刚刚得到的所有内存归零,通常的调用是
memset(assign_value, 0, 10);
(代替malloc
,您也可以使用calloc
。一旦malloc
和calloc
之间的区别是calloc
会自动将新分配的内存初始化为全部0。)
如果你使用assign_value
作为字符串,并且你想让它以一个空字符串开始,你不必把它全部清零。只需在第一个位置放一个空字符就足够了:
*assign_value = ' ';
一旦执行了这些操作,assign_value
将保存一个长度为0的空字符串。因此,您的测试if(strlen(assign_value) == 0)
总是会成功的,在以后的代码中,您总是会调用strcpy
,而不是strcat
。
最后,作为边点,在调用malloc
时,不必乘以sizeof(char)
,也不必强制转换结果。所以你可以使用更简单的:
char *assign_value = malloc(10);
(您不必乘以sizeof(char)
,因为根据定义,sizeof(char)
总是恰好为1。您不必在C中显式强制转换malloc
的结果,如果这样做,它可以隐藏错误。)
malloc()
分配内存,但不初始化它。无论分配的内存位置发生了什么,都是您得到的
因此,当使用malloc
时,最好创建并初始化缓冲区:
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
为了获得更多阅读,这里有一个讨论,比较malloc()和calloc()。
请注意,没有必要像在c++中那样在c中强制转换[m][c]alloc的输出。