使用C中的双指针在结构数组中进行内存分配

时间:2018-03-30 06:36:28

标签: c arrays pointers struct

下面是使用双指针填充struct R数组的示例代码。我无法为r[0]分配内存,而且当函数退出时,rr[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;
}

我无法找到背后的原因。任何帮助都将受到高度赞赏。

3 个答案:

答案 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;
}