I have the following structs as example:
#define MAX_PEOPLE 16
typedef struct {
int age;
}Person;
typedef struct {
Person *people;
int numPeople;
}Team;
I'm trying to allocate an array of persons in a function, passed by parameters. My Team is supposed to store an array of 16 pointers of Person. I can't figure out what I'm doing wrong.
void initiateTeam(Team * team){
team->numPeople = MAX_PEOPLE;
Person *p[MAX_PEOPLE];
for(int i=0; i<MAX_PEOPLE;i++){
p[i] = malloc(sizeof(Person);
}
team->people = &p[0];
}
I printed out the addresses of my team->people[i] and I'm getting random junk. Why is the assingment team->people = &p[0] wrong? Shouldn't it get the first address of my array then perform pointer arithmetic?
5 Answers 5
You are pointing team->people to a statically defined array of person pointers. Once the function ends, the stack pointer moves back to where main left off, erasing all previously local memory in the addPeople function. You need to malloc p, and return it from the function
3 Comments
p) is on the stack, not 'statically'.Since in the comments you stated that you're trying to allocate an array of Person objects and not pointers, you should rather do:
void addPeople(Team * team){
team->numPeople = MAX_PEOPLE;
team->people = malloc(sizeof(Person) * MAX_PEOPLE);
}
mind that there's no * in sizeof since you don't want an array of pointers but of objects. You will later be able to access the single elements (i.e. each Person object) with
team->people[2].age = 25; // The third person in the array
Finally, remember to free your memory.
Comments
your variable p is allocated in the stack of the addPeople() function. The assignment team->people = &p[0] (which is equivalent to team->people = p) is valid but dangerous because that address will be invalid as soon as the function is finished.
Better create p with malloc(sizeof (Person *) * MAX_PEOPLE) instead of using the stack.
Comments
The problem is here:
Person *p[MAX_PEOPLE];
This allocates a local variable in the function to hold the array of people pointers.
You get the address of this local variable and send it back. As soon as you are not in the function the local data is freed. It was just allocated locally. It is no longer valid. I might work for a while or it might not depending on the the program does next.
You want this:
Person **p = (Person **)malloc(sizeof (Person *) * MAX_PEOPLE);
Comments
I think you are getting the thing with pointer and memory management in C a little bit wrong. Consider reading a little bit more about it, before you continue coding your application.
Beside, I think you do not need an array of pointers to persons, but an array of persons. Your struct is correct, but I would implement your function like that:
void addPeople(Team * team){
team->numPeople = MAX_PEOPLE;
team->people = malloc(sizeof(Person) * MAX_PEOPLE);
}
And do not forget to free() your team->people.
But if MAX_PEOPLE is an pre processor define, then it is totally unnecessary to use memory from the heap. If you are not storing too many people in your struct, the stack can easily fulfill your requirements.
2 Comments
people memory, how can I access then second, third, person in my people's memory when it's not an array.Person *people; variable. Just make sure, that the pointer points to a big enough space of memory, and that you do not access memory outside of its borders.
Peoplefrom myTeam,