Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

A step by step compiler says "Invalid write of size 4", while in general it's a segmentation fault. I don't understand how to solve this. I have been fidgeting with this for the past few hours. What am I missing?

typedef struct Person{
  int age;
  char name[6]
} Person;

fun(Person **parray){
  *parray = realloc(*parray, 6 * (sizeof(Person)));
    for(int i = 0; i < 6; ++i){
      strcpy (parray[i]->name, "John");
      parray[i]->age = 15;
    }
}

int main() {
  Person *parray;
  
  parray = calloc(0, sizeof(Person));
  
  fun(&parray);
  
  return 0;
}
question from:https://stackoverflow.com/questions/65894702/i-simplified-a-part-of-my-project-to-solve-this-specific-problem-i-have-invalid

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
1.2k views
Welcome To Ask or Share your Answers For Others

1 Answer

I don't understand how to solve this.

The first step should be to enable compiler warnings, and fix all the bugs the compiler tells you about. If you are using gcc, turn on -Wall -Wextra flags.

Now, the bug is in that parray[i] inside fun() is not the correct expression -- it treats parray as pointer to an array, when in fact parray points to a single variable (of the same name) in main().

You can fix this by using the correct expression: (*parray)[i].

A better fix is to avoid the double pointer altogether, e.g.:

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

typedef struct Person{
  int age;
  char name[6]
} Person;

Person *fun(Person *parray){
  Person *result = realloc(parray, 6 * (sizeof(Person)));
  for(int i = 0; i < 6; ++i){
    strcpy(result[i].name, "John");
    result[i].age = 15;
  }
  return result;
}

int main()
{
  Person *parray = calloc(0, sizeof(Person));
  parray = fun(parray);

  free(parray);
  return 0;
}

If you insist on passing a double-pointer into fun() and updating it inside, you can do that, while still minimizing the use of the double-pointer, like so:

void fun(Person **parray){
  Person *p = *parray = realloc(*parray, 6 * (sizeof(Person)));
  for(int i = 0; i < 6; ++i){
    strcpy(p[i].name, "John");
    p[i].age = 15;
  }
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...