简体   繁体   中英

Why does my void pointer change values in my program?

I have a the following in a header file.

struct SortedList
{
    void * data;         
    struct SortedList * next;       
    struct SortedList * previous;
    int (*compareFunc)(void *, void *);
    void (*destructor)(void *);
};
typedef struct SortedList* SortedListPtr;

SortedListPtr SLCreate(CompareFuncT cf, DestructFuncT df);

In a .c file, I implemented the SLCreate function.

SortedListPtr SLCreate(CompareFuncT cf, DestructFuncT df)
{
    struct SortedList item;         
    item.data = malloc(100);
    item.data = NULL;           
    item.next = (struct SortedList *) malloc(sizeof(struct SortedList));
    item.previous = (struct SortedList *) malloc(sizeof(struct SortedList));
    item.compareFunc = cf;
    item.destructor = df;
    SortedListPtr ptr = (struct SortedList *) malloc(sizeof(struct SortedList));    
    ptr = &item;
    return ptr;
};

In main.c, I try to do the following: SortedListPtr list = SLCreate(&compareInts, &destroy);

//...... A bunch other code that does not alter list or it's contents at all. 



struct SortedList item = (*list);
void * data = item.data;

if (data != NULL)   
{
    printf("Why did data become not null???\n");
}

So why is is that data is not null as I directed it in my SLCreate function? I thought I used malloc and what can I do to solve this?

You are returning the address of a local variable, which is undefined behaviour in C.

If you want to return a pointer, the memory it points to must live outside the scope of the function returning it. Because you are returning a pointer to the local variable item , that memory location is no longer available when the function returns.

I think you got mixed up. You did allocate memory, but copied it incorrectly.

SortedListPtr ptr = (struct SortedList *) malloc(sizeof(struct SortedList));    
ptr = &item;

Here you replace the pointer with the address of the local item . Instead, that last line should be:

*ptr = item;

The above will copy all the data stored in item to the memory location referenced by ptr .

One more thing... I'm pretty sure you shouldn't be allocating stuff for previous and next . Just set them to NULL . I can't be certain without seeing how you plan to use this, but I can see you're confused about pointers. This would be more "normal":

item.next = NULL;
item.previous = NULL;

may be this way can reduce copy. since i am not sure if you has a copy structor

SortedListPtr SLCreate(CompareFuncT cf, DestructFuncT df)
{
    SortedListPtr ptr = (struct SortedList *) malloc(sizeof(struct SortedList));    

    ptr->data = malloc(100);
    ptr->data = NULL;           
    ptr->next = (struct SortedList *) malloc(sizeof(struct SortedList));
    ptr->previous = (struct SortedList *) malloc(sizeof(struct SortedList));
    ptr->compareFunc = cf;
    ptr->destructor = df;
    return ptr;
};

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