typedef struct unit_class_struct {
char *name;
} person;
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array->name = strdup("Robert");
array++;
array->name = strdup("Jose");
return array;
}
int main()
{
person *array;
array = setName();
printf("First name is %s\n", array[0].name);
printf("Second name is %s\n", array[1].name);
return 0;
}
在这个例子中,array [0] .name返回Jose,而不是我预期的Robert,而array [1] .name是空的。
但是,如果我使用
person * setName() {
person * array;
person * array_switch;
array = malloc (2 * sizeof(person));
array_switch = array;
array_switch->name = strdup("Robert");
array_switch++;
array_switch->name = strdup("Jose");
return array;
}
它按预期工作。 array.name [0]返回Robert,array.name [1]返回Jose。
为什么它需要第二个指针才能使用此示例?我可以不使用第二个指针而仍然使用指针算法吗?
我已经知道这是另一种方法:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array[0].name = strdup("Robert");
array[1].name = strdup("Jose");
return array;
}
答案 0 :(得分:18)
在您的代码中:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array->name = strdup("Robert");
array++;
array->name = strdup("Jose");
return array;
}
为数组中的两个元素分配空间,并将array
设置为指向第一个:
+-------+ +----------+
| array | ---> | array[0] |
+-------+ +----------+
| array[1] |
+----------+
然后用array++
和递增元素指针,最后返回到调用函数。该指针指向第二个数组元素,这就是为什么它似乎是错误的(为什么当你试图在以后尝试释放该内存时几乎肯定会崩溃):
+-------+ +----------+
| array | -+ | array[0] |
+-------+ | +----------+
+-> | array[1] |
+----------+
您需要的是:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array[0].name = strdup("Robert");
array[1].name = strdup("Jose");
return array;
}
正如你已经指出的那样。此解决方案不根本不会更改array
指针。但是,如果你真的想使用指针,你可以在返回之前用array++
反转array--
的操作,以便将array
设置回正确的值:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
array->name = strdup("Robert");
array++;
array->name = strdup("Jose");
array--;
return array;
}
或者,另一种不改变原始指针的方法,不使用数组索引而不使用第二个指针就是使用指针算法。编译器知道指针指向哪种类型,因此可以正确调整指针以找到下一个元素(您已经知道它知道如何执行此操作,因为array++
是array = array + 1
的简写,并且该语句调整了值也正确):
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
(array+0)->name = strdup("Robert");
(array+1)->name = strdup("Jose");
return array;
}
答案 1 :(得分:2)
您只需执行简单的算术指针操作,如加法和减法:
array->name = "Robert";
(array+1)->name = "Jose";
return array;
答案 2 :(得分:1)
由于您增加了array
,因此您不再有指向[0]
元素的指针,而是指向[1]
元素的指针。这样做:
array->name = strdup("Robert");
array++;
array->name = strdup("Jose");
return array - 1;
请注意,在C p[x]
中只有*(p + x)
,或者,如果您愿意,请考虑以下内容:(p + x)[0]
。最后一种情况是您的程序实际执行的操作,x
== 1.因此(p + 1)[1]
与p[2]
相同,并且没有任何内容,因此您的结果为空。
(你也可以把它写成......
array++->name = strdup("Robert");
array--->name = strdup("Jose");
return array;
...但是如果你这样做,一群人会来和你一起投票。真的难以读懂吗?我们的目标是只写出没有灵感的笨重代码?)
答案 3 :(得分:1)
指针实际上只是 数字 (内存中的地址)。您正在修改此指针以指向其他位置,然后将其返回。
答案 4 :(得分:1)
这将使用指针算法,并保留原始数组指针:
person * setName() {
person * array;
array = malloc (2 * sizeof(person));
(array+0)->name = strdup("Robert");
(array+1)->name = strdup("Jose");
return array;
}