下面是使用双指针填充struct R
数组的示例代码。我无法为r[0]
分配内存,而且当函数退出时,r
和r[0]
都会变为0x0
。
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct R
{
int x;
int y;
char * z;
};
void func(struct R **r)
{
r = (struct R **) malloc(4 * sizeof(struct R *));
r[0] = (struct R *) malloc(sizeof(struct R)); // giving r[0] = 0x0
r[0]->x = 1;
r[0]->y = 2;
r[0]->z = (char *) malloc(64 * sizeof(char));
strcpy(r[0]->z , "HELLO");
}
int main()
{
struct R *r = NULL;
func(&r);
printf("%d", r->x);
printf("%d", r->y);
printf("%s", r->z);
return 0;
}
我无法找到背后的原因。任何帮助都将受到高度赞赏。
答案 0 :(得分:7)
该行
r = (struct R **) malloc(4 * sizeof(struct R *));
更改r
指向的位置,但仅在函数中本地指向。它不会更改调用函数中指针的值。
您需要的是:
void func(struct R **r)
{
*r = malloc(sizeof(struct R));
r[0]->x = 1;
r[0]->y = 2;
r[0]->z = malloc(64 * sizeof(char));
strcpy(r[0]->z , "HELLO");
}
另一种选择是将func
的返回值更改为指针并使其更易于使用。
struct R * func()
{
struct R *r = malloc(sizeof(*r));
r->x = 1;
r->y = 2;
r->z = malloc(64 * sizeof(char));
strcpy(r->z , "HELLO");
return r;
}
并在main
中将其用作:
struct R *r = func();
PS 请参阅Do I cast the result of malloc?,了解为什么不应该转换malloc
的返回值。
答案 1 :(得分:4)
你想要一个struct R
的数组,那你为什么要为struct R
的指针数组保留空间?
更改为:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
struct R
{
int x;
int y;
char * z;
};
void func(struct R **r)
{
/* Dereference in order to change the value of r */
*r = malloc(4 * sizeof(struct R)); /* Don't cast malloc */
r[0]->x = 1;
r[0]->y = 2;
r[0]->z = malloc(64); /* char is always 1 byte */
strcpy(r[0]->z , "HELLO");
}
int main(void) /* Correct prototype */
{
struct R *r = NULL;
func(&r);
printf("%d", r[0].x);
printf("%d", r[0].y);
printf("%s", r[0].z);
/* Don't forget to free */
free(r[0].z);
free(r);
return 0;
}
答案 2 :(得分:1)
这一行:
void func(struct R **r)
{
r = (struct R **) malloc(4 * sizeof(struct R *));
无论r
是什么类型,它仍然是一个局部变量。如果指定局部变量,则调用者部分不会受到影响。此代码类似于
void func(int r)
{
r = 1;
}