Jaspar
Jaspar

Reputation: 25

Struct pointer contains pointer to char (string) , how to allocate memory for it?

Excuse my english , my program crashes as it is , but when i change the struct member *name (string) to name[50] and remove the command (students+i)->name = (char*)malloc(50 * sizeof(char)); the program works fine , so i guess the problem is that i do something wrong when dynamically allocating memory for each name.

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

struct student
{
    char *name;
    int grade;
};

int main()
{
    int student_number = 0,i;
    struct student *students = NULL;

    printf("Give the number of students: ");
    scanf("%d",&student_number);

    students = (struct student*)malloc(student_number * sizeof(struct student));

    for(i=0;i<student_number;i++)
    {
        (students+i)->name = (char*)malloc(50 * sizeof(char));

        system("CLS");

        printf("Give the name of student no. %d: ",i+1);
        scanf(" %s",&(students+i)->name);
        printf("Give the grade of student no. %d: ",i+1);
        scanf("%d",&(students+i)->grade);
    }

    system("CLS");

    for(i=0;i<student_number;i++)
    {
        printf("%d. %s %d\n",i+1,(students+i)->name,(students+i)->grade);
    }

    system("PAUSE");
    return 0;
}

Upvotes: 0

Views: 92

Answers (2)

David R
David R

Reputation: 1

Firstly, remove the '&' in the scanf(" %s" &(students+i)->name) This is because it is already a pointer, and the '&' makes it a pointer to a pointer when it asks for just a pointer. After adding this change it works fine for me.

Upvotes: 0

user202729
user202729

Reputation: 3993

Some of the correct ways to call C scanf function are:

scanf("%d", int*)
scanf("%s", char*)

This is incorrect:

scanf("%s", char**)

Consider the working code:

int grade;
char name [50];
scanf("%d", &grade);
scanf("%s", name);

Here grade is an int variable, so &grade is the pointer to a int variable, having type int*. So this is correct.

name is an array of char, when passed to scanf it decays to a char pointer (type char*) point to the first element of the array. So this is also correct.

char name [50];
scanf("%s", &name);

&name is a pointer to an array of 50 chars, having type char(*)[50], so technically this is incorrect, but it happens to work because the pointer have the same value as &name[0] or (char*) name.

struct a { int x; int y; };
a b;
scanf("%d", &b);

This code is also wrong, but happens to work because &b have the same value (most of the time) as &b.x, so the code will have identical functionality to

scanf("%d", &b.x);

although the pointer types are different. Don't rely on the behavior, anyway.

int grade;
scanf("%d", grade);

This crashes because grade is not a pointer to a int.

Now consider dynamically allocated array (of course, remember to call free(name) when you've done using it).

char* name;
name = (char*) malloc(50 * sizeof(char));

Consider using calloc instead. But anyway, in this case, name is a char pointer that point to the first byte of the allocated memory. So

scanf("%s", name)

is correct, because name is a char* pointing to the allocated memory, as I said above.

scanf("%s", &name)

&name is the pointer to the char pointer name, having type char**. Incorrect.


In conclusion, use & wisely. Don't stick to the pattern scanf("format", &variables).


Unrelated note: Don't use (students+i)->name, use students[i].name instead. It's much clearer.

Upvotes: 1

Related Questions