【问题标题】:Dynamic Allocation of an Array of Strings in CC中字符串数组的动态分配
【发布时间】:2013-03-09 17:31:22
【问题描述】:

对于家庭作业,我需要定义一个将内存分配给字符串数组(在结构中)的函数。

给定每个字符串的长度:MAX_WORD_LEN+1 (=10+1) 我必须为len 的字符串数量分配内存,len 在输入中收到。

带有字符串数组定义的结构体(给定):

struct dict{
    int len;
    char (*dict0)[MAX_WORD_LEN+1];
    char (*dict1)[MAX_WORD_LEN+1];
};

我看不懂char (*dict0)[MAX_WORD_LEN+1];的声明

  • 函数声明也给出:
    void createDict(struct dict* myDict);

这是我写的,但我不确定它是否有效,而且我很难在编译器中检查它。我也是根据这个网站和其他网站的帖子写的,不太明白:

选项 1:

void createDict(struct dict* myDict)
{

    myDict->(*dict0) =  malloc( (myDict->len)*sizeof(char*));
    myDict->(*dict1) = (char**) malloc( (myDict->len)*sizeof(char*));

    for(int i=0;i<(myDict->len);i++)
    {
        (myDict->(*dict0)[i]) = (char*)malloc((MAX_WORD_LEN+1)*sizeof(char));
        (myDict->(*dict0)[i]) = (char*)malloc((MAX_WORD_LEN+1)*sizeof(char));
    }
}

选项 2:

(myDict->(*dict0)[MAX_WORD_LEN+1]) = malloc((myDict->len) * sizeof(char*));
(myDict->(*dict1)[MAX_WORD_LEN+1]) = malloc((myDict->len) * sizeof(char*));

请给我解释一下……

【问题讨论】:

  • 该声明都不正确。单独的编译器应该会告诉你。
  • 字符 (*dict0)[MAX_WORD_LEN+1];表示字符指针数组。但似乎您正在尝试存储一个字符数组(AKA 字符串)
  • @Ifthikhan 这不是 MAX_WORD_LEN+1 个字符指针的数组。它是一个指向 MAX_WORD_LEN+1 个字符数组的类型指针。如果没有围绕*dict 的括号,您将是正确的。如前所述,您不是。

标签: c arrays string pointers malloc


【解决方案1】:

首先你需要了解以下三种声明的区别。为简洁起见,假设 N 是 MAX_WORD_LEN+1 以匹配您的大小:

char data[N];      // array of N chars
char *data[N];     // array of N char *pointers* (i.e. char *)
char (*data)[N];   // pointer to array of N chars

记住,最重要的是,指针是变量,它持有一个“地址”并且是实现定义的。就像int 变量保存实现整数的值一样,指针变量保存实现地址。

在几乎所有情况下,您都可以使用 sizeof() 运算符正确地为指针类型 malloc() 内存,并取消引用底层目标。在某些情况下,这并不直观或易于呈现,但以下内容应该有所帮助:

// allocates sizeof(Type) block
Type *p = malloc(sizeof(*p));

// allocates N*sizeof(Type) contiguous blocks
//  note: we'll use this style later to answer your question
Type *pa = malloc(N * sizeof(*pa));

无论Type 是什么,这都会起作用。这很重要,因为在您的情况下,您有一个指针声明为:

char (*dict)[N];

正如我们上面已经讨论过的,这声明了一个类型的指针(pointer-to-N-chars)。请注意,尚未分配实际内存。这只是一个指针;仅此而已。因此,您可以使用上述语法安全地分配单个元素:

// allocate single block
char (*dict)[N] = malloc(sizeof(*dict));

但这仅占一个条目。你需要len 条目,所以:

// allocate 'len' contiguous blocks each N chars in size
char (*dict)[N] = malloc(len * sizeof(*dict));

现在dict 可以安全地作为从 0..(len-1) 开始的数组寻址。您可以复制您的数据,例如:

strcpy(data[0], "test");
strcpy(data[1], "another test");

只要源字符串不超过 N 个字符(包括零终止符),就可以正常工作。

最后,完成后不要忘记释放您的分配:

free(dict);

剧透

myDict->dict0 =  malloc( myDict->len * sizeof(*(myDict->dict0)));
myDict->dict1 =  malloc( myDict->len * sizeof(*(myDict->dict1)));

【讨论】:

  • @user2191288 我当然希望它有所帮助。
【解决方案2】:

在结构的声明中,

char (*dict0)[MAX_WORD_LEN+1];

表示dict0MAX_WORD_LEN + 1 元素的字符数组的pointer,即char [11]

要初始化对象的字段,可以考虑如下所示的示例

void createDict(struct dict* myDict)
{
    myDict->dict0 = &glbarr;
    myDict->dict1 = &glbarr;
}

其中glbarr 是一个全局数组,定义为

char glbarr[MAX_WORD_LEN+1];

【讨论】:

  • [MAX_WORD_LEN+1] - 是数组中每个字符串的长度,我必须根据我从输入中获得的 int "len" 为数组分配内存。例如,如果 len 为 5,我需要为 5 个长度为 11 的字符串分配内存……我不确定你写的是什么。
【解决方案3】:

char (*dict)[MAX_WORD_LEN+1] 是指向char[MAX_WORD_LEN+1] 数组的指针。或者您可以将其解释为此类数组的数组(二维数组)。

让我们说 typedef char MyString[MAX_WORD_LEN+1];.

那么您的声明将显示为MyString *dict0; 换句话说,dict0 可以是指向MyString 数组的第一个元素的指针。这就是你应该做的。

我不会发布详细的解决方案(你的老师会不满意的)。

我还建议你感受一下char (*dict)[10];char *dict[10]; 之间的区别。

【讨论】:

  • 我不明白其中的区别,也不是我真正的功课。我明年开始学习,到那时我正在做一些练习。
  • 所以我需要为指针 dict0 分配内存?这是这样写的吗? (myDict->(*dict0)[MAX_WORD_LEN+1]) = malloc((myDict->len) * sizeof(char)); \n 我在选项 2 中写的内容
  • char *dict[10] 是一个指针数组,而不是指向数组的指针。你应该 malloc len*(MAX_WORD_LEN+1)*sizeof(char) 字节。这看起来像 myDict->dict0 = malloc(...)
  • 我问了关于 char(*dict)[11] 的问题,我认为它是一个指向 chars 数组的指针 - 一个字符串,如上一个答案中所说,......或者不是?跨度>
  • @EL11 用于描述指针绑定的类型。例如char *p;,基础类型是char。对于char (*p)[N];,基础类型是char[N]。我希望这让它更清楚一点。这很重要,尤其是在进行指针运算时,因为基础类型的大小决定了在添加/减去缩放器时指针实际调整的字节数。
猜你喜欢
  • 2011-10-21
  • 1970-01-01
  • 2015-07-14
  • 2020-12-09
  • 1970-01-01
  • 2015-03-09
  • 1970-01-01
相关资源
最近更新 更多