Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
1.2k views
in Technique[技术] by (71.8m points)

dynamic memory allocation - I simplified a part of my project to solve this specific problem I have (invalid write of size 4/segmentation fault)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...