我最近决定提高我的C知识(我剩下的一点点)。我很快意识到第一个技能变得多云是内存管理。诅咒。
我认为最好的办法就是写一些无意义的指针练习。第一个是分配一个包含4个char数组的数组,每个数组的长度都是可变的。
该代码的简化版本:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main()
{
char **aStr = malloc(4*sizeof(aStr));
int j = 0;
int i = 0;
while(i<sizeof(aStr))
{
j = 4 + 2*i;//in my code, length is determined by arguments
aStr[i] = malloc(j*sizeof(aStr[i]));
j--;
strncpy(aStr[i],"RaisinRubarbCarrot"+i,j);
aStr[i][j] = 0;//just a habbit
j++;
printf("ptr@:%p\n\tkey:%d\n\tval:%s\n\tlength:%d (%d)\n\n",*aStr[i],i,aStr[i],j,strlen(aStr[i]));
i++;
}
free(aStr);
return 0;
}
我觉得这很笨重,反直觉。今天我想起了我的旧nemisis:calloc
。然后我写了
char **aStr = (char **)calloc(4, sizeof(char *));
并在循环中:
aStr[i] = (char *) calloc(j,sizeof(char *));
我找到了编写最后一行的代码示例:
aStr[i] = (char *) calloc(j,sizeof(char));//without the asterisk
问题1:有什么区别,如果有的话?
问题2:是否有另一种分配字符串数组的方法?我现在看到代码的方式,感觉/看起来我首先将4个指针分配给单个char指针,然后分配每个指针所需的实际大小。那只是感觉不对。
然后我可能会错误地将所有这些全部放在一起,在这种情况下:随意地将我的头撞到墙上并指出我在阅读浪费你所有时间之前阅读的体面手册的方向。 。
答案 0 :(得分:3)
char *
和char
是两种不同的类型,并且具有不同的数据大小。 char
始终是单个字节,因此sizeof(char)
始终 1 。另一方面,指向char 的指针在32位系统上将是4个字节。因此,如果您使用sizeof(char*)
为字符串分配空间,您将分配的内容远远超出您的需要。
使用循环来分配单个字符串很好。假设字符串的最大长度,你可以只分配一个大块,但那会很笨拙。
答案 1 :(得分:1)
您应该使用sizeof(char)而不是sizeof(char *),因为您正在尝试为字符数组分配内存,而不是为字符分配poiners数组。所以这是正确的版本:
aStr[i] = (char*) calloc(j, sizeof(char));
//first argument number of memory
//locations to be allocated
//second argument, size of each location
calloc相对于malloc的区别/优势在于它还将内存位置初始化为0。
首先为chars分配一个包含4个指针的数组。然后,为每个字符串分配内存(以前分配的4个指针中的每一个将指向其中一个数组)