简体   繁体   中英

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

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 (ie as a local variable in main ).

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

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.

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM