Search code examples
cpointersmallocstructurerealloc

Structer pointer and pointer char array malloc array


I want to do structer array but I don't know structer array size therefore I need to use pointer structer and I want to do char array in the structer and I don't know char array size therefore I need to use pointer char in this structer but I don't understand malloc and realloc functions. How can I do this ?

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

struct School{
    char *school_name;
    int student_size;
}*high_school;




void createSchool(struct School *s, char *schl_name, int student, int school_size)
{
    int i = 0;

    if(school_size == 1){
        s = (struct School*) malloc(sizeof(struct School));
    }
    else{
        s = (struct School*) realloc(s, (school_size*sizeof(struct School)));
    }

    (s+(school_size-1))->student_size = student;
    (s+(school_size-1))->school_name = (char *) malloc(20); // 20 it is not important

    (s+(school_size-1))->school_name = schl_name;
     for(i; i<school_size; i++){
        printf("%s\t%d\n",(s+i)->school_name, (s+i)->student_size);
    }
    printf("\n\n");
}

int main()
{
    int i = 1;
    createSchool(high_school, "Harvard", 50, i);
    i++;
    createSchool(high_school, "Oxford", 40, i);
    i++;
    createSchool(high_school, "MIT", 30, i);
}

I want to do screen shoot:

Harvard 50

Harvard 50
Oxford 40

Harvard 50
Oxford 40
MIT 30

but screen shoot of program :

Harvard 50


└1q     7405760
Oxford  40


        7405760
(null)  0
MIT     30

Solution

  • Your pointer inside createSchool has local scope, so global pointer is not modified. Faster fix is to return new allocated memory back to caller.

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct School{
        char *school_name;
        int student_size;
    }*high_school;
    
    struct School* createSchool(struct School *s, char *schl_name, int student, int school_size)
    {
    
        if(school_size == 1)
        {
            s = malloc(sizeof(struct School));
        }
        else
        {
            s = realloc(s, (school_size*sizeof(struct School)));
        }
    
        if (s != NULL)
        {
            s[school_size-1].student_size = student;
            s[school_size-1].school_name = malloc(strlen(schl_name)+1);
    
            strcpy(s[school_size-1].school_name, schl_name);
    
            for(int i=0; i<school_size; i++)
            {
                printf("%s\t%d\n", s[i].school_name, s[i].student_size);
            }
            printf("\n\n");
        }
    
        return s;
    }
    
    int main(void)
    {
        int i = 1;
        high_school = createSchool(high_school, "Harvard", 50, i);
        i++;
        high_school = createSchool(high_school, "Oxford", 40, i);
        i++;
        high_school = createSchool(high_school, "MIT", 30, i);
    }
    
    1. Minimal signature for main is int main (void)
    2. Take note that malloc/realloc returned value have to be checked.
    3. With your code, in case of realloc fails, you are loosing the pointer to the already allocated memory. So you should use a temp pointer to store the realloc result and check for integrity. After that you can reassign it ot your pointer.

    struct School* createSchool(struct School *s, char *schl_name, int student, int school_size)
    {
    
        if(school_size == 1){
            s = malloc(sizeof(struct School));
        }
        else
        {
            struct School *temp = realloc(s, (school_size*sizeof(struct School)));
    
            if (temp == NULL)
                return s;
    
            s = temp;    
        }
    
        if (s != NULL)
        {
            s[school_size-1].student_size = student;
            s[school_size-1].school_name = malloc(strlen(schl_name)+1);
    
            strcpy(s[school_size-1].school_name, schl_name);
    
            for(int i=0; i<school_size; i++)
            {
                printf("%s\t%d\n", s[i].school_name, s[i].student_size);
            }
            printf("\n\n");
        }
    
        return s;
    }
    

    Different solution can be implemented using double pointer:

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    struct School{
        char *school_name;
        int student_size;
    }*high_school;
    
    void createSchool(struct School **s, char *schl_name, int student, int school_size)
    {
    
        if(school_size == 1)
        {
            *s = malloc(sizeof(struct School));
        }
        else
        {
            struct School *temp = realloc(*s, (school_size*sizeof(struct School)));
    
            if (temp == NULL)
                return;
    
            *s = temp;
        }
    
        if (*s != NULL)
        {
            (*s)[school_size-1].student_size = student;
            (*s)[school_size-1].school_name = malloc(strlen(schl_name)+1);
    
            strcpy((*s)[school_size-1].school_name, schl_name);
    
            for(int i=0; i<school_size; i++)
            {
                printf("%s\t%d\n", (*s)[i].school_name, (*s)[i].student_size);
            }
            printf("\n\n");
        }
    }
    
    int main(void)
    {
        int i = 1;
        createSchool(&high_school, "Harvard", 50, i);
        i++;
        createSchool(&high_school, "Oxford", 40, i);
        i++;
        createSchool(&high_school, "MIT", 30, i);
    }
    

    Last thing take note that,to assign the name of school you can simply use:

        (*s)[school_size-1].school_name = schl_name;