0

我最近决定复习我的 C 知识(我只剩下一点点)。我很快意识到,第一个变得模糊的技能是内存管理。该死的。

我决定最好的办法是写一些毫无意义的指针练习。第一个是分配一个由 4 个字符数组组成的数组,每个字符数组的长度都是可变的。

该代码的简化版本:

#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;
}

我觉得这很笨拙,而且违反直觉。今天我想起了我的宿敌: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 指针,然后分配每个指针所需的实际大小。只是感觉不对。

再说一次,我可能对所有这一切都错了,在这种情况下:随意将我的头撞在墙上,并指出我应该阅读一本体面的手册的方向,然后再浪费你所有的时间......

4

2 回答 2

3

char *并且char是两种不同的类型,并且具有不同的数据大小。Achar总是一个字节,所以sizeof(char)总是1。另一方面,指向 char的指针在 32 位系统上将是 4 个字节。因此,如果您使用sizeof(char*)为字符串分配空间,您将分配比您需要的更多的空间。

使用循环分配单个字符串很好。假设你的字符串有一个最大长度,你可以只分配一个大块,但这会很笨拙。

于 2012-08-13T22:48:05.780 回答
1
  1. 您应该使用 sizeof(char) 而不是 sizeof(char*) 因为您正在尝试为字符数组而不是字符指针数组分配内存。所以这是正确的版本:

    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。

  2. 您首先分配 4 个指向字符的指针的数组。然后,为每个字符串分配内存(之前分配的 4 个指针中的每一个都将指向这些数组之一)

于 2012-08-13T22:52:07.080 回答