Question

I keep geeting a segfault in the main function. I create a pointer to a struct I created and I pass it's reference to another function which allocates and reallocates memory. Then accessing it in the main function (where it was originally defined) causes a segfault.

Here is my test code:

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

typedef struct {
  char desc[20];
  int nr;
} Kap;

void read(Kap *k);

int main(void) {
  Kap *k = NULL;
  read(k);

  printf("__%s %d\n", k[4].desc, k[4].nr);
  return 0;
}

void read(Kap *k) {
  int size = 3;
  k = (Kap*) calloc(size, sizeof(Kap));

  k[0].nr = 1;
  k[1].nr = 2;
  k[2].nr = 3;

  strcpy(k[0].desc, "hello0");
  strcpy(k[1].desc, "hello1");
  strcpy(k[2].desc, "hello2");

  size *= 2;
  k = (Kap*) realloc(k, sizeof(Kap)*size);
  if(k == NULL) {
    printf("ERROR\n");
    exit(EXIT_FAILURE);
  }


  k[3].nr = 4;
  k[4].nr = 5;
  k[5].nr = 6;

  strcpy(k[3].desc, "hello3");
  strcpy(k[4].desc, "hello4");
  strcpy(k[5].desc, "hello5");
}

What am I doing wrong?

Was it helpful?

Solution

Here's a simplified version of the problem you are having:

#include <stdio.h>

void func(int x)
{
    x = 10;
}

int main()
{
    int x = 5;
    printf("x = %d\n", x);
    func(x);
    printf("x = %d\n", x);
}

The same reason x does not change is the reason that k does not change in your program. A simple way to fix it is this:

Kap *read()
{
    Kap *k = calloc(...);
    ...
    k = realloc(k, ...);
    ...
    return k;
}

int main()
{
    Kap *k = read();
    ...
}

OTHER TIPS

The problem is you're not passing the pointer back to main(). Try something like this instead:

Kap * read();

int main(void) {
  Kap *k = read();

  printf("__%s %d\n", k[4].desc, k[4].nr);
  return 0;
}

Kap * read() {
    ... everything else you're already doing ...
    return k;
}

The code you showed passes a pointer by value into read(). The subroutine can use that pointer (though it's kind of useless since its local copy is immediately changed), however changes made within read() do not bubble back to its caller.

My suggestion is one method of allowing read() to send the new pointer back up, and it's probably the right method to choose. Another method is to change read()s signature to be void read(Kap **);, where it will receive a pointer to a pointer -- allowing it to modify the caller's pointer (due to being passed by reference).

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top