user1177044
user1177044

Reputation: 41

Accessing dynamically allocated nested struct in C

The structs are as follows, inner structs are inside outer structs. Both structs are dynamically allocated. The problem arises when I try to access an inner struct by means of a reference to change the address value.

For example:

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);
    }

}

How can I access outerArray[3][innerStruct[4], the 4th outer struct's 5th inner struct and change its address value?

Upvotes: 2

Views: 3224

Answers (2)

alk
alk

Reputation: 70911

Prints member address of 5th inner strucuture of 4th outer structure, copies data into it and prints it again:

#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;
}

The next time you post code please be so kind and make it compile.

Upvotes: 0

Adam Liss
Adam Liss

Reputation: 48290

Declare innerStruct as an inner *, rather than a struct inner if you want to use malloc().

As you've declared it, the memory for inner is allocated when you create an outer.

Note also that, since you've used typedef, you don't need the struct keyword when you declare a variable of that type.

Here's a corrected version of your code that compiles and runs:

#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;
}

Upvotes: 2

Related Questions