Let's say I have an array of pointers to structs. How do I make it so every element of the array points to a different memory location, so I can change these struct values through pointers individually?
Some example code:
struct Person {
int age;
char *name[64];
}
int main() {
struct Person *people[4];
struct Person tmp_person;
people[0] = &tmp_person;
people[0]->age = 12;
people[0]->name = "John";
people[1] = &tmp_person;
people[1]->age = 34;
people[1]->name = "Mike";
}
Here, every person element will be the same since all the array elements point to the same memory (tmp_person
). I know the code is incorrect, I'm just trying to make an example. So how do I make unique pointers? Creating a new variable for every element (tmp_person1
, tmp_person2
, ...) seems stupid and really hard.
Let's say I have an array of pointers to structs. How do I make it so every element of the array points to a different memory location, so I can change these struct values through pointers individually?
Some example code:
struct Person {
int age;
char *name[64];
}
int main() {
struct Person *people[4];
struct Person tmp_person;
people[0] = &tmp_person;
people[0]->age = 12;
people[0]->name = "John";
people[1] = &tmp_person;
people[1]->age = 34;
people[1]->name = "Mike";
}
Here, every person element will be the same since all the array elements point to the same memory (tmp_person
). I know the code is incorrect, I'm just trying to make an example. So how do I make unique pointers? Creating a new variable for every element (tmp_person1
, tmp_person2
, ...) seems stupid and really hard.
2 Answers
Reset to default 4As dbush said: The more typical case, and probably what you (don't know you) want is an array of objects, not only pointers to objects:
#include <stdio.h>
#include <stdlib.h>
struct Person {
int age;
const char *name;
};
void print_persons(const struct Person *persons, int arrSz)
{
for( int i=0; i<arrSz; i++)
{
printf("Person %s, age %d\n", persons[i].name, persons[i].age);
}
}
int main() {
struct Person people[2];
people[0].age = 12;
people[0].name = "John";
people[1].age = 34;
people[1].name = "Mike";
struct Person others[]
= { {23, "Jim"},
{24, "Joe"},
{25, "Jack"}
};
// Use pointers:
struct Person *peoplePtrs[2];
peoplePtrs[0] = malloc(sizeof(struct Person));
peoplePtrs[0]->age = 12;
peoplePtrs[0]->name = "JohnPtr";
peoplePtrs[1] = malloc(sizeof(struct Person));
peoplePtrs[1]->age = 34;
peoplePtrs[1]->name = "MikePtr";
print_persons(people, sizeof people/sizeof *people);
print_persons(others, sizeof others/sizeof *others);
for( int i=0; i<sizeof peoplePtrs/sizeof *peoplePtrs; i++)
{
printf("Person %s, age %d\n", peoplePtrs[i]->name, peoplePtrs[i]->age);
}
// good form to free the allocated memory, even though it is
// not really necessary at the end of a program
free(peoplePtrs[0]);
free(peoplePtrs[1]);
}
I corrected the type of name
to a simple pointer; that works best with static strings as in your example. You could use an array of chars but you'd have to initialize them with strcpy
or memcpy
— one cannot assign arrays.
I also showed you how to initialize the array directly which works if you know the data at programming time, as in your example.
You can surely use an array of pointers to structs, as shown in the last part; typically, the objects pointed to would be dynamically allocated with malloc (and later freed).
And I wrote a little function that prints a person just to show the contents.
malloc
can be used to allocate memory as needed.
With struct Person *people
multiple structure can be allocated to the pointer. This example allocates memory for three structures.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
int age;
char name[64];
};
int main ( void) {
struct Person *people = NULL;
if ( NULL == ( people = malloc ( sizeof *people * 3))) {
fprintf ( stderr, "problem malloc\n");
return 1;
}
people[0].age = 12;
strcpy ( people[0].name, "John");
people[1].age = 34;
strcpy ( people[1].name, "Mike");
people[2].age = 22;
strcpy ( people[2].name, "Alice");
for ( int each = 0; each < 3; ++each) {
printf ( "age %d\n", people[each].age);
printf ( "name %s\n", people[each].name);
}
free ( people);
}
With an array of pointers, memory can be allocated to each pointer.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct Person {
int age;
char name[64];
};
int main ( void) {
struct Person *people[4] = { NULL};
for ( int each = 0; each < 4; ++each) {
if ( NULL == ( people[each] = malloc ( sizeof (struct Person)))) {
fprintf ( stderr, "problem malloc\n");
while ( each) {
--each;
free ( people[each]);
}
return 1;
}
}
people[0]->age = 12;
strcpy ( people[0]->name, "John");
people[1]->age = 34;
strcpy ( people[1]->name, "Mike");
people[2]->age = 22;
strcpy ( people[2]->name, "Alice");
people[3]->age = 28;
strcpy ( people[3]->name, "April");
for ( int each = 0; each < 4; ++each) {
printf ( "age %d\n", people[each]->age);
printf ( "name %s\n", people[each]->name);
}
for ( int each = 0; each < 4; ++each) {
free ( people[each]);
}
}
char *name[64];
will create an array of 64 elements of typechar *
. Is this intended? I believe you may want to remove the*
, so that you instead have an array of 64 elements of typechar
. However, if you do this, then you will have to usestrcpy
instead of=
to set the content of the array. – Andreas Wenzel Commented Mar 4 at 15:50person1
,person2
,person3
,person4
and make the pointers in the array to point those variables address or else usemalloc
todynamically allocate
4 different pointers. – Nalan PandiKumar Commented Mar 4 at 16:03struct Person
for every pointer in the array, but this does not make much sense if you have an array of a known size likestruct Person *people[4];
– Bodo Commented Mar 4 at 17:52malloc()
either, but if there's a way to solve my problem with it I'll try to look into it, thanks! – SuperCarrot Commented Mar 4 at 18:18