C语言中字符串数组的动态分配

el1*_*l11 1 c arrays string malloc pointers

对于家庭工作,我需要定义一个将内存分配给字符串数组的函数(它是一个结构体).

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

带有字符串数组的struct(给定):

struct dict{
    int len;
    char (*dict0)[MAX_WORD_LEN+1];
    char (*dict1)[MAX_WORD_LEN+1];
};
Run Code Online (Sandbox Code Playgroud)

我不明白这个宣言 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));
    }
}
Run Code Online (Sandbox Code Playgroud)

方案2:

(myDict->(*dict0)[MAX_WORD_LEN+1]) = malloc((myDict->len) * sizeof(char*));
(myDict->(*dict1)[MAX_WORD_LEN+1]) = malloc((myDict->len) * sizeof(char*));
Run Code Online (Sandbox Code Playgroud)

请向我解释......

Who*_*aig 7

首先,您需要了解以下三个声明之间的区别.为简洁起见,假设NMAX_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
Run Code Online (Sandbox Code Playgroud)

请记住,指针是包含"地址"并且是实现定义的变量.就像int变量保存实现整数的值一样,指针变量保存实现地址.

在几乎所有情况下,您都可以malloc()使用sizeof()运算符正确记忆指针类型,并且基础目标已取消引用.在某些情况下,这不是直观或容易呈现,但以下情况应该有所帮助:

// 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));
Run Code Online (Sandbox Code Playgroud)

无论是什么,这都会有效Type.这很重要,因为在你的情况下你有一个指针声明为:

char (*dict)[N];
Run Code Online (Sandbox Code Playgroud)

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

// allocate single block
char (*dict)[N] = malloc(sizeof(*dict));
Run Code Online (Sandbox Code Playgroud)

但这只占一个条目.你需要len条目,所以:

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

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

strcpy(data[0], "test");
strcpy(data[1], "another test");
Run Code Online (Sandbox Code Playgroud)

只要源字符串不超过N-chars(包括零终止符),这将正常工作.

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

free(dict);
Run Code Online (Sandbox Code Playgroud)

扰流板

myDict->dict0 =  malloc( myDict->len * sizeof(*(myDict->dict0)));
myDict->dict1 =  malloc( myDict->len * sizeof(*(myDict->dict1)));
Run Code Online (Sandbox Code Playgroud)