什么是 char **text = (char **) malloc(n * sizeof(char*));做?

What does char **text = (char **) malloc(n * sizeof(char*)); does?

我刚开始编程,我不知道这是什么意思..

我尽力了..

我知道它的动态内存分配,但不知道所有这些(星星)是什么意思。 有人可以向我解释一下,每种类型是什么吗? 这是代码:

char **text = (char **) malloc(n * sizeof(char*));
text[i] = (char *) malloc(MAX_LENG);

代码分配(动态)内存以保存 n 个字符串。这些字符串中的每一个都具有最大长度 MAX_LENG - 1.

我假设完整的原始代码是:

char **text = (char **) malloc(n * sizeof(char*));
for (int i = 0; i < n; ++i)
    text[i] = (char *) malloc(MAX_LENG);

或没有不必要的转换:

char **text = malloc(n * sizeof(char*));
for (int i = 0; i < n; ++i)
    text[i] = malloc(MAX_LENG);

所以第一行,即

char **text = malloc(n * sizeof(char*));

会给你一个指向内存区域的指针,其中包含 n 个指向字符的指针

循环,即

for (int i = 0; i < n; ++i)
    text[i] = malloc(MAX_LENG);

然后使这些 n 指针中的每一个都指向具有 MAX_LENG 个字符的内存区域。

看起来像:

所以在这之后你有 n 个字符串的记忆并且可以像这样使用它们:

strcpy(text[0], "HELLO");  // First string is "Hello"
strcpy(text[1], "WORLD");  // Second string is "World"

之后它看起来像:

您可以像这样访问各个字符

char c = text[1][4]; // c now holds the character 'D' from the string "WORLD"

一个简单的解释可以看下面的方式。假设您有一个指向字符串文字的指针数组。例如

char * s[] = { "Hello ", "World!" };

在极少数情况下,表达式中使用的数组指示符被转换为指向其第一个元素的指针。所以在大多数情况下,数组指示符 s 被转换为类型 char ** 的指针。也就是说它是一个指向 char *.

类型对象的指针

例如

char **p = s;

取消引用指针,您将获得数组的第一个元素,该元素的类型又是 char *。例如

#include <stdio.h>

int main( void )
{
    enum { N = 2 };
    char * s[N] = { "Hello ", "World!" };
    
    for ( char **p = s; p != s + N; ++p )
    {
        printf( "%s", *p );
    }
    
    putchar( '\n' );
    
    return 0;
}

程序输出为

Hello World!

现在假设你想动态分配数组。该数组具有 N 个类型为 char * 的元素。

所以你需要写出表达式

malloc( N * sizeof( char * ) )

函数调用 return 指向已分配内存范围开始的指针,其中将有类型 char * 的第一个元素。那就是函数 return 是一个类型为 void * 的指针,它可能指向动态分配数组的第一个元素。

所以你需要写

char **p = malloc( N * sizeof( char * ) );

char **p = ( char ** )malloc( N * sizeof( char * ) );

类似于上面的声明

char **p = s;

其他答案解释了它的作用,但我想关注一个小细节。

char **text = malloc(n * sizeof(char*));

sizeof 中使用类型而不是对象被认为是一种不好的做法。为什么?如果更改对象的类型,则需要更改旧类型的所有可能外观。如果您在 sizeof 中使用该对象 - 每个 sizeof 都将被正确计算而无需更改代码。

char **text = malloc(n * sizeof(*text));