user1729422
user1729422

Reputation: 341

Segfault error when using realloc on a dynamic array of structs

I have a problem with a big piece of code, so I reduced it as much as I was able to, in fact I found a solution to my problem, but I'm almost sure there is a better solution, that's why I'm asking for help.

Here's the bad code:

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

typedef struct{
  int a;
}my_struct;

void tab_add(my_struct** tab, int i){
  *tab = (my_struct*)realloc(*tab, i+1); // Here's the realloc

  printf("Adding struct number %d\n", i);
  tab[i]->a = i*8; // Problem here, when accessing tab[i] the second time
  printf("Struct added\n");
}

int main(void){
  my_struct* tab = NULL;

  tab_add(&tab, 0);
  tab_add(&tab, 1);
  tab_add(&tab, 2);

  return 0;
}

The output is:

Adding struct number 0
Struct added
Adding struct number 1
zsh: segmentation fault ./main

Now, here's a code that solve the problem (but it creates a useless variable...):

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

typedef struct{
  int a;
}my_struct;

void tab_add(my_struct** tab, int i){
  *tab = (my_struct*)realloc(*tab, i+1);

  printf("Adding struct number %d\n", i);
  my_struct st; // Useless variable created
  st.a = i*8;
  (*tab)[i] = st;
  printf("Struct added\n");
}

int main(void){
  my_struct* tab = NULL;

  tab_add(&tab, 0);
  tab_add(&tab, 1);
  tab_add(&tab, 2);

  return 0;
}

Its output is correct:

Adding struct number 0
Struct added
Adding struct number 1
Struct added
Adding struct number 2
Struct added

Thanks for reading :)

Upvotes: 1

Views: 435

Answers (4)

simonc
simonc

Reputation: 42165

See the realloc man page. The second argument is be the size of data you want to allocate; I think you're passing an array index instead.

The code should ideally be of the form

my_struct* tmp = realloc(*tab, sizeof(my_struct) * (i+1));
if (tmp == NULL) {
    /* error handling goes here */
else {
    *tab = tmp;
}

to cope with realloc failing and returning NULL.

Upvotes: 1

Adnan Akbar
Adnan Akbar

Reputation: 718

Not sure what you are trying to achieve here. According to realloc documentation it try to increase the size of allocated space if possible , if not it is like free and malloc again. So in your case each time if you are trying to allocate a space for a struct it will be the same. But according to the code it is 0 bytes first time and it will try to free (allocated memory which is none and so is the seg fault).

Also what you say is a fix doesnt seem to be a fix. It will still die at some point later. Because stack gets corrupted already at the first call.

Upvotes: 0

Hernan Velasquez
Hernan Velasquez

Reputation: 2820

It's as simple as making this assigment:

(*tab)[i].a = i*8;

If you want to get rid of st.

Upvotes: 1

Doug Currie
Doug Currie

Reputation: 41180

You should use

(*tab)[i].a = i*8;

to access the field a

Upvotes: 2

Related Questions