char** args = (char**)malloc(MAX_ARGS*sizeof(char*));
和
char* args = (char*)malloc(MAX_ARGS*sizeof(char*));
请解释这两种声明之间的区别。为什么我们需要2颗星,为什么需要1星?
答案 0 :(得分:3)
在这两种情况下,演员都是不必要的,可以掩盖错误;我将在下面删除演员表。 (malloc()
返回void*
,可以隐式转换为指向任何指针。)
char **args = malloc(MAX_ARGS*sizeof(char*));
这将args
定义为指向char的指针,并将其初始化为指向一大块内存,足以容纳MAX_ARGS
个元素,每个元素都是{{} 1}}。完成此操作后,您需要为这些char*
元素指定值,这可能会使它们指向字符串。
char*
这是 legal ,但几乎肯定是一个逻辑错误。 char *args = malloc(MAX_ARGS*sizeof(char*));
是一个指向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);
为ptr
,然后FOO*
与sizeof *ptr
相同 - 但如果您稍后更改{{},则无需更新该行1}}成为sizeof (FOO)
BAR`。
在你的情况下,指向类型本身就是一个指针,所以你可以写:
ptr
当你致电pointer to
时,你应该总是检查它是否成功,并在失败时采取一些行动 - 即使该行动是终止程序并显示错误消息:
char **args = malloc(MAX_ARGS * sizeof *args);
答案 1 :(得分: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样式字符串。
答案 2 :(得分:0)
2颗星就像矩阵(或二维数组)。第一个malloc只获取第一行的内存(你必须迭代它的元素,使第二个malloc为其他元素保留空间)。