Raluca Damaris Lupeş
Raluca Damaris Lupeş

Reputation: 11

allocating memory with malloc()

In the program below I am trying to make the function insert() to allocate memory by calling malloc() to create a new struct (person)...but I get the following warning: assignment from incompatible pointer type [enabled by default]...How should I use the malloc() function?

#include <stdio.h>
/* these arrays are just used to give the parameters to 'insert',
   to create the 'people' array 
*/

#define HOW_MANY 7
char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim",
              "Harriet"};
int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24};

typedef struct
{
  char *name;
  int age;
}person;


static void insert(person *p, char *name, int age) 
{
  p = (struct person *)malloc(sizeof(person));
  p->name = name;
  p->age = age;
}

int main(int argc, char **argv) 
{

  person people[7];

  for (int i = 0; i < 7; i++) 
  {
    insert (&people[i], names[i], ages[i]);
  }

  for (int i = 0; i < 7; i++) 
  {
    printf ("name: %s, age: %i\n", people[i].name, people[i].age);
  }
  return 0;
}

Upvotes: 0

Views: 513

Answers (3)

Sourav Ghosh
Sourav Ghosh

Reputation: 134396

Have a closer look at your code.

person people[7];

people is an array of 7 elements of type person, where all the elements are allocated memory at compile time (loosely speaking), there's no need of run-time allocation here. You're won't be needing the malloc(), in first place.

That said, if you want dynamic allocation, then, you will need the person to be an array of 7 pointer variables to type person and you can allocate memory to the individual pointer inside the insert() function. Something like person *people[7]; can be of use there. Also, you need to include stdlib.h to have the prototype of malloc() and family. That is one of the reasons for why not to cast the return value of malloc() and family in C..

That way, your function prototype will also change. You have to

  • accept a person **p
  • operate on (*p) inside the insert() function, and finally,
  • in main(), you have to use pointer member reference operator -> while printing the values of individual elements.

Upvotes: 1

RoadRunner
RoadRunner

Reputation: 26335

You can try something like this, but it really depends on how you are gathering you're data. But with the array you have described it is possible this way.

Although, for you're specific situation, where you have declared 7 persons, it is best to not use malloc(). If you don't know how many persons there will be, then malloc() is a good choice.

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

#define HOW_MANY 7

typedef struct{
   char *name;
  int age;
}person_t;

typedef struct {
    person_t *person;
    int numpersons;
} all_person_t;

all_person_t *initialize_persons(void);
void insert(all_person_t *persons, char *name, int age, int count);
void print_persons(all_person_t *persons);
void insert_each_person(all_person_t *persons, char *names[], int ages[]);
void free_persons(all_person_t *persons);

int
main(int argc, char const *argv[]) {
    char *names[HOW_MANY]= {"Simon", "Suzie", "Alfred", "Chip", "John", "Tim", "Harriet"};
    int ages[HOW_MANY]= {22, 24, 106, 6, 18, 32, 24};

    all_person_t *persons;

    persons = initialize_persons();

    insert_each_person(persons, names, ages);

    print_persons(persons);

    free_persons(persons);

    return 0;
}

void
insert_each_person(all_person_t *persons, char *names[], int ages[]) {
    int i;

    persons->person = malloc(persons->numpersons *sizeof(person_t));

    for (i = 0; i < persons->numpersons; i++) {
        insert(persons, names[i], ages[i], i);
    }
}

all_person_t
*initialize_persons(void) {
    all_person_t *persons;
    persons = malloc(sizeof(*persons));
    persons->numpersons = HOW_MANY;
    return persons;
}

void
insert(all_person_t *persons, char *name, int age, int count) {
    persons->person[count].name = malloc(strlen(name)+1);

    strcpy(persons->person[count].name, name);
    persons->person[count].age = age;
}

void
print_persons(all_person_t *persons) {
    int i;

    for (i = 0; i < persons->numpersons; i++) {
         printf("%s %d\n", persons->person[i].name, persons->person[i].age);
    }
}

void
free_persons(all_person_t *persons) {
    int i;

    for (i = 0; i < persons->numpersons; i++) {
        free(persons->person[i].name);
    }
    free(persons->person);
    free(persons);
}

Upvotes: 0

dbush
dbush

Reputation: 225007

You're casting the result of malloc to struct person *, but p is of type person *. They are not the same thing. The first is the tag name of a struct (which in this case doesn't exist) while the other is a typedef which aliases (in this case) an unnamed struct.

You actually shouldn't be casting the result value of malloc as that can cause other errors.

Additionally, you shouldn't be using malloc at all. You pass in the address of a person structure, so there is already memory allocated for it (i.e. as a local variable in main).

Get rid of the malloc and that will fix the issue.

Upvotes: 4

Related Questions