Passing a Structure by reference to a function that will dynamically create and fill a array of structures

和自甴很熟 提交于 2021-01-29 13:54:14

问题


I want to pass a structure pointer to a function that will dynamically create a array of structures at the location pointed to by the structure pointer that was passed. I am able to create and fill the array of structure successfully but when trying to print the data in the calling function using the pointer that was passed gives me a garbage values. Please help me know why my structure pointer is pointing to garbage and how can I access my data correctly.

The following is just some example code to demonstrate how the structure is passed and dynamically filled using malloc & realloc. this is INCORRECT method:

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

struct student 
{
    int id;
    char name[20];
    float percentage;
};

void func(struct student *record);

int main() 
{
    struct student *record = NULL;

    record = (struct student *)malloc(sizeof(struct student));

    func(record);

    if(record != NULL)
    {
        for(int i=0; i<2; i++)
        {
            printf(" 1 Id is: %d \n", record[i].id);
            printf(" 1 Name is: %s \n", record[i].name);
            printf(" 1 Percentage is: %f \n", record[i].percentage);
            printf("\n");
        }
    }
    else
    {
        printf("record pointer is null");
    }

    return 0;
}

void func(struct student *record1)
{
    for(int i=0; i<2; i++)
    {
        if(i)
        {
            record1 = (struct student *)realloc(record1,sizeof(struct student)*(i+1));
        }
        record1[i].id=1;
        strcpy(record1[i].name, "Raju");
        record1[i].percentage = 86.5;
    }
}

The following is a similar example using double pointer which is the CORRECT way to do this:

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

struct student 
{
    int id;
    char name[20];
    float percentage;
};

void func(struct student **record);

int main() 
{
    struct student *record = NULL;

    func(&record);

    if(record != NULL)
    {
        for(int i=0; i<2; i++)
        {
            printf(" 1 Id is: %d \n", record[i].id);
            printf(" 1 Name is: %s \n", record[i].name);
            printf(" 1 Percentage is: %f \n", record[i].percentage);
            printf("\n");
        }
    }
    else
    {
        printf("record pointer is null");
    }

    free(record);

    return 0;
}

void func(struct student **record1)
{
    *record1 = (struct student *)malloc(sizeof(struct student));
    for(int i=0; i<2; i++)
    {
        if(i)
        {
            *record1 = (struct student *)realloc(*record1,sizeof(struct student)*(i+1));
        }
        (*record1)[i].id=1;
        strcpy((*record1)[i].name, "Raju");
        (*record1)[i].percentage = 86.5;
    }
}

回答1:


Your first solution,

record1 = (struct student *)realloc(record1,sizeof(struct student)*(i+1));

works as long as realloc does not have to move the pointer! That is, realloc just expands the memory area it gave earlier to record1. Should, at some later stage, realloc be required to give you another piece of memory, then the earlier pointer record in main will become invalid and could now contain your "garbage".

As you were thinking, you need a double pointer to be able to see the changed pointer in main. You were nearly there, just a typo:

*record1 = (struct student *)realloc(record1,sizeof(struct student)*(i+1));

in the above line the second occurrence of record1 must also be dereferenced, so *record1 because you must give realloc the original pointer.

Oh, and don't cast the result of malloc! Although the compiler does not complain, it can cause future problems.



来源:https://stackoverflow.com/questions/48274749/passing-a-structure-by-reference-to-a-function-that-will-dynamically-create-and

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!