0

I am trying to pass the pointer to a struct to a function to create an array of the struct there. The overall idea is:

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

typedef struct items
{
  int number;
  char *name;
  char *description;
} ITEMS;

int process(ITEMS **items)
{
  int i = 0, something = 200;
  // for loop is for the representation. 
  // The actual data come from MySQL row loop
  for (int j = 100; j < something; j++)
  {
    // Growing the array of struct
    items = realloc(items, (i + 1) * sizeof(*items));

    // Adding items here
    items[i]->number = j;
    strcpy(items[i]->name, "Some name"); // it comes from a variable
    strcpy(items[i]->description, "Some text");
    i++;
  }

  return i;
}

int main()
{

  ITEMS *items;
  int num_items = process(&items);

  for (int i = 0; i < num_items; i++)
  {
    printf("%d - %s - %s\n", items[i].number, items[i].name,
        items[i].description);
  }
  return 0;
}

but I am struggling with reallocating the memory for the struct (and with the pointers too).

4
  • 2
    realloc just reallocates the main array and then memcpys the contents in. It doesn't allocate new separate memory for name or description which need to be allocated independently the way you have things described. Also if i always starts at 0 then this can only ever allocate 2 items. You need to pass the existing length or have some way of finding the length Commented Sep 20, 2022 at 12:53
  • 2
    The notation ITEMS *items[] in the the function parameter list would serve you better! Commented Sep 20, 2022 at 12:56
  • 1
    @JardelLucca Opinion: disagree, that just hides the fact it's a pointer to pointer. It's better to just be explicit about what you have instead of risking confusion. Commented Sep 20, 2022 at 12:57
  • 2
    You are making a realloc on an uninitialized pointer! Commented Sep 20, 2022 at 13:03

1 Answer 1

4

The pointer to pointer must be de-referenced in the function so the allocation is visible in the calling function.
strdup is use to allocate memory to the pointers in the structure.
It is better to use a temporary variable for the reallocation.

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

typedef struct items
{
  int number;
  char *name;
  char *description;
} ITEMS;

int process(ITEMS **items)
{
  int i = 0;
  // Growing the array of struct
  *items = realloc(*items, (i + 1) * sizeof(**items));
  // repeating this step in a loop of adding items

  // Adding items here
  (*items)[i].number = 72;
  (*items)[i].name = strdup( "Some name"); // it comes from a variable
  (*items)[i].description = strdup ("Some text");
  i++;

  *items = realloc(*items, (i + 1) * sizeof(**items));
  // another item
  (*items)[i].number = 88;
  (*items)[i].name = strdup( "Some name"); // it comes from a variable
  (*items)[i].description = strdup ("Some text");
  i++;

  return i;
}

int main()
{

  ITEMS *items = NULL;
  int num_items = process(&items);

  for (int i = 0; i < num_items; i++)
  {
    printf("%d - %s - %s\n", items[i].number, items[i].name, items[i].description);
  }
  return 0;
}

With better error detection

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

typedef struct items
{
  int number;
  char *name;
  char *description;
} ITEMS;

int process(ITEMS **items)
{
    ITEMS *temp = NULL;
    int i = 0;
    // Growing the array of struct
    if ( NULL == ( temp = realloc(*items, (i + 1) * sizeof(**items)))) {
        fprintf ( stderr, "realloc problem\n");
        return i;
    }
    *items = temp;
    // repeating this step in a loop of adding items

    // Adding items here
    (*items)[i].number = 72;
    (*items)[i].name = strdup( "Some name"); // it comes from a variable
    (*items)[i].description = strdup ("Some text");
    i++;

    if ( NULL == ( temp = realloc(*items, (i + 1) * sizeof(**items)))) {
        fprintf ( stderr, "realloc problem\n");
        return i;
    }
    *items = temp;
    // another item
    (*items)[i].number = 88;
    (*items)[i].name = strdup( "Some name"); // it comes from a variable
    (*items)[i].description = strdup ("Some text");
    i++;

    return i;
}

int main()
{

    ITEMS *items = NULL;
    int num_items = process(&items);

    for (int i = 0; i < num_items; i++)
    {
        printf("%d - %s - %s\n", items[i].number, items[i].name, items[i].description);
    }
    return 0;
}
Sign up to request clarification or add additional context in comments.

1 Comment

And typedef struct item { ... } item_t or such would be more logical.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.