【问题标题】:Accessing dynamically allocated nested struct in C在 C 中访问动态分配的嵌套结构
【发布时间】:2012-04-29 21:30:25
【问题描述】:

结构如下,内部结构在外部结构内部。两个结构都是动态分配的。当我尝试通过引用来访问内部结构以更改地址值时,就会出现问题。

例如:

typedef struct{
    char address[32];
}inner;

typedef struct{
    struct inner innerStruct;
}outer;

main(){

    int i = 0;
    outer* outerArray;
    outer* outerReference;
    inner* innerReference;

    /* create 20 outer structs */
    outerArray = malloc(20 * sizeof(outerArray*));

    /* for each outer struct, dynamically allocate 10 inner structs */

    for(i = 0; i < 10; i++)
    {
        outerReference = outerArray + i;
        outerReference->innerStruct = malloc(10 * sizeof(outerReference->innerStruct);
    }

}

如何访问outerArray[3][innerStruct[4],第4个外部结构的第5个内部结构并更改其地址值?

【问题讨论】:

  • 该代码无法编译(出于多种原因)。您似乎将指针与对象实例混为一谈。
  • 为什么投反对票?对于学习驾驭复杂结构、指针和内存分配的人来说,这似乎是一个完全合理的问题。

标签: c struct nested dynamic-arrays dereference


【解决方案1】:

如果您想使用malloc(),请将innerStruct 声明为inner *,而不是struct inner

正如您所声明的,inner 的内存是在您创建 outer 时分配的。

还要注意,由于您使用了typedef,因此在声明该类型的变量时不需要struct 关键字。

这是您的代码的更正版本,可以编译并运行:

#include <stdio.h>
#include <stdlib.h>

typedef struct {
  char address[32];  // 32 chars are allocated when an inner is created
} inner;

typedef struct {
  inner innerStruct;  // innerStruct is allocated when an outer is created
} outer;

typedef struct {
  inner *innerStruct;  // innerStruct must be allocated explicitly
} outer2;

int main(int argc, char *argv[]) {
  int i = 0;
  outer  *outerArray;
  outer2 *outer2Array;

  outer  *outerReference;
  outer2 *outer2Reference;

  /* create 20 outer structs (should check for out-of-mem error) */
  outerArray = malloc(20 * sizeof(outer));

  for (i = 0; i < 10; ++i) {
    outerReference = outerArray + i; // ptr to i'th outer
    // Note: innerStruct.address bcz it's a structure
    sprintf(outerReference->innerStruct.address, "outer struct %d", i);
  }

  /* create 20 outer2 structs */
  outer2Array = malloc(20 * sizeof(outer2));

  /* for each outer struct, dynamically allocate 10 inner structs */
  for (i = 0; i < 10; ++i) {
    outer2Reference = outer2Array + i;
    outer2Reference->innerStruct = malloc(sizeof(inner));
    // Note: innerStruct->address bcz it's a pointer
    sprintf(outer2Reference->innerStruct->address, "outer2 struct %d", i);
  }

  /* print all the data and free malloc'ed memory */
  for (i = 0; i < 10; ++i) {
    printf("outer: %-20s, outer2: %-20s\n",
      outerArray[i].innerStruct.address,
      outer2Array[i].innerStruct->address);
      free(outer2Array[i].innerStruct);
  }
  free(outer2Array);
  free(outerArray);
  return 0;
}

【讨论】:

  • 拜托上帝不 void main 出于多种原因,它是如此糟糕。 faq.cprogramming.com/cgi-bin/…
  • @lukecampbell:很好,谢谢。已更正,并提供了另一个很好的参考:users.aber.ac.uk/auj/voidmain.cgi
  • 我觉得这会打印出每个外部结构的第一个内部结构的地址。不会有2个for循环吗?第一个循环遍历外部结构,嵌套循环遍历每个外部结构的内部结构?
  • @user1177044 如果您为每个外部结构分配了多个内部结构,则可以这样做。使用指针而不是对象有几个不同的原因。您可能需要一个数组,或者您可能只想将内存动态分配给单个对象。
【解决方案2】:

打印第四个外部结构的第五个内部结构的成员address,将数据复制到其中并再次打印:

#include <stdio.h>
#include <stdlib.h>

typedef struct{
    char address[32];
}inner;

typedef struct{
    inner* innerStruct;
}outer;

int main()
{
    int i = 0;
    outer* outerArray;
    outer* outerReference;
    /* inner* innerReference; */ /* unused */

    /* create 20 outer structs */
    outerArray = malloc(20 * sizeof(*outerArray));

    /* for each outer struct, dynamically allocate 10 inner structs */

    for(i = 0; i < 10; i++)
    {
        outerReference = outerArray + i;
        outerReference->innerStruct = malloc(10 * sizeof(*outerReference->innerStruct));
    }

    printf("address: '%s'\n", outerArray[3].innerStruct[4].address);

    strcpy(outerArray[3].innerStruct[4].address, "<emtpy>");

    printf("address: '%s'\n", outerArray[3].innerStruct[4].address);

    return 0;
}

下次您发布代码时,请善待并编译。

【讨论】:

    猜你喜欢
    • 2021-07-22
    • 1970-01-01
    • 1970-01-01
    • 2021-11-08
    • 1970-01-01
    • 1970-01-01
    • 2017-02-19
    • 1970-01-01
    相关资源
    最近更新 更多