1
char** args = (char**)malloc(MAX_ARGS*sizeof(char*));

char* args = (char*)malloc(MAX_ARGS*sizeof(char*));

请解释这两种声明之间的区别。为什么我们需要 2 星,为什么需要 1 星?

4

3 回答 3

3

在这两种情况下,强制转换都是不必要的,并且可以掩盖错误;我将在下面删除演员表。(malloc()返回 a void*,它可以隐式转换为指向任何对象的指针。)

char **args = malloc(MAX_ARGS*sizeof(char*));

这定义args为一个指向字符的指针,并将其初始化为指向一块足够大的内存来保存MAX_ARGS元素,每个元素都是一个char*. 完成此操作后,您将需要为这些char*元素分配值,可能使它们指向字符串。

char *args = malloc(MAX_ARGS*sizeof(char*));

这是合法的,但几乎可以肯定是一个逻辑错误。 args是一个指向字符的指针,这意味着它可以指向单个char对象,也可以指向元素数组的第一个char元素。但是您正在分配可以容纳MAX_ARGS 指针的内存。

更有可能做的是:

char *s = malloc(MAX_LEN);

这将导致s指向可以保存MAX_LEN char元素的内存区域(长度为 的字符串MAX_LEN - 1)。(请注意,sizeof (char) == 1根据定义。)

有一个有用的技巧可以避免类型不匹配。FOO*对于任何类型,类型的指针都FOO需要指向一块足够大的内存,以容纳旧的一个或多个类型的元素FOO。如果你写:

ptr = malloc(count * sizeof *ptr);

and ptris a FOO*, then与 --sizeof *ptr相同,sizeof (FOO)但如果您稍后更改ptrpointer toBAR`,则不必更新该行。

在您的情况下,指向的类型本身就是一个指针,因此您可以编写:

char **args = malloc(MAX_ARGS * sizeof *args);

当你调用 时malloc,你应该总是检查它是否成功,如果失败则采取一些行动——即使那个行动是用错误信息终止程序:

if (args == NULL) {
    fprintf(stderr, "malloc failed\n");
    exit(EXIT_FAILURE);
}
于 2013-02-27T01:00:06.323 回答
0

两颗星表示指向指针类型到数据类型的指针。所以在 char** 的情况下,这意味着创建一个 char*[MAX_ARGS] 数组。

因此,对于这种情况,以下内容将是有效的,因为args[n]char*

args[0] = (char*)strdup("aaa");
args[1] = (char*)strdup("bbbb");
args[2] = (char*)strdup("ccccc");

注意:您应该记住在释放 args 之前释放数组的每个成员,否则指针会丢失。

使用单个星,它只是一个指向数据的指针,本质上您正在编写 char[MAX_ARGS*sizeof(char*)]

对于这个args[n]是一个char类型:

args[0] = 'a';
args[1] = 'b';
args[2] = 'c';

使用这个 char 数组,您将创建一个简单的字符数组,也称为 c 样式字符串。

于 2013-02-27T00:31:39.370 回答
0

2 颗星就像矩阵(或二维数组)。第一个 malloc 只为第一行获取内存(您必须遍历其元素,使第二个 malloc 为其他的保留空间)。

于 2013-02-27T00:37:47.947 回答