开发者

C: How to free memory to struct when not having a pointer to it anymore?

开发者 https://www.devze.com 2023-02-09 01:14 出处:网络
I have a function that makes a structure and returns the new structure itself. The structure contains an array of numbers and an integer showing how many numbers there are(this works like an array).

I have a function that makes a structure and returns the new structure itself. The structure contains an array of numbers and an integer showing how many numbers there are(this works like an array). So I have makeStruct that makes a temporary struct and then returns it. In main I call this function and assign it to my structure myNumbers. This has as an effect that in the function there is created an instance of a structure, copied to myNumbers and then deleted. Is my assumption correct?

This seems to compile correctly but I can't see a way to free the memory allocated as there is no pointer pointing to my structure. How can I free memory?

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

typedef struct{
    int* numbers; /*array of numbers*/
    int  crowd; /*crowd of numbers*/
} magicNums;

magicNums makeStruct(int crowd){
    magicNums tempStruct, *struct_ptr=&tempStruct; /*开发者_运维知识库my temp struct and its pointer*/
    struct_ptr=(magicNums*)malloc(sizeof(magicNums)); /*allocating memory for struct*/
    tempStruct.numbers=(int*)malloc(sizeof(int)*crowd); /*allocating memory for struct's numbers*/
    return tempStruct;
}

int main() {
    magicNums myNumbers;
    myNumbers=makeStruct(10);
    /*magicNums *myNumbers_ptr=&myNumbers;  This won't work             */
    /*free(myNumbers_ptr);                  This won't work             */
    /*free(&myNumbers);                     This won't work             */
    return 0;
}


As to answer your question, "How to free memory to struct when not having a pointer to it anymore?".

You can't. Your code leaks memory.

There's however many errors in your code that makes no sense

 magicNums tempStruct, *struct_ptr=&tempStruct;
 struct_ptr=(magicNums*)malloc(sizeof(magicNums)); 

The above two lines first sets struct_ptr = &tempStruct; , and later on replaces that pointer with the return from malloc. The 2 lines accomplish exactly the same as:

 magicNums tempStruct;
 magicNums *struct_ptr;
 struct_ptr=(magicNums*)malloc(sizeof(magicNums)); 

That might make it more clear as to what's going on.

return tempStruct;

By returning tempStruct here, you have lost the pointer to struct_ptr, so you cannot free it, and you leak memory.

You have not lost the pointer to tempStruct.numbers though. You can free that in your main:

magicNums myNumbers;
myNumbers=makeStruct(10);
free(myNumbers.numbers);

magicNums is not a pointer, you can't and don't need to free that. You're returning a struct by value, so that's ok - there's no dynamically memory involved there.


That is correct, you cannot free the memory as you have no valid pointer to it. You have successfully created a memory leak.

You will need to return a struct pointer from that function, and not a struct by value.

Why are you using malloc() for this in the first place?


Try returning the pointer instead.

magicNums* makeStruct(int crowd){
    magicNums *tempStruct = (magicNums*)malloc(sizeof(magicNums)); /*allocating memory for struct*/

    tempStruct->numbers=(int*)malloc(sizeof(int)*crowd); /*allocating memory for struct's numbers*/
    return tempStruct;
}

int main() {
    magicNums *myNumbers;
    myNumbers = makeStruct(10);

    free(myNumbers->numbers);
    free(myNumbers);
    return 0;
}


There are a lot of problems here. For one, to answer the question -- you can't. But, that's not really your problem here:

I'm going to guess that you want this instead:

magicNums* makeStruct(int crowd){
    magicNums *struct_ptr = 
        (magicNums*)malloc(sizeof(magicNums)); /*allocating memory for struct*/
    struct_ptr->crowd = crowd;
    struct_ptr->numbers=(int*)malloc(sizeof(int)*crowd); /*allocating memory for struct's numbers*/
    return struct_ptr;
}

Then main would be

int main() {
    magicNums *myNumbers;
    myNumbers = makeStruct(10);

    free (myNumbers->numbers);        
    free (myNumbers);

    return 0;
}


You don't need to allocate memory for the struct itself, your makeStruct should look like this:

magicNums makeStruct(int crowd) {
    magicNums tempStruct;
    tempStruct.numbers = (int *) malloc(sizeof(int) * crowd);
    tempStruct.crowd = crowd;
    return tempStruct;
}

Although tempStruct is created on the stack and automatically freed when the function returns, the function will make a copy of tempStruct and return that.

then you could use it like this:

int main() {
    magicNums myNumbers;
    myNumbers = makeStruct(10);
    free(myNumbers.numbers);
}


How to free memory to struct when not having a pointer to it anymore?

Good luck with that! If you don't know where it is, how can you hope to free it? Solution: remember where you put it!


As far as I can see, you just don't need the first malloc inside makeStruct.

Then later in your int main(void) (!) you may do

free(myNumbers.numbers);


You might do the cleanup in the function itself, while returning a copy of the structure to the main program. Then you will have a reference to that copy, and will be able to free it after use in order to reclaim memory.

Edit: see Martins answer, which might be exactly what you want :)


Here is code that matches your description of what you think you're doing. Whether that is what you want to do, I don't know.

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

typedef struct{
    int* numbers; /*array of numbers*/
    int  crowd; /*crowd of numbers*/
} magicNums;

magicNums makeStruct(int crowd){
    magicNums tempStruct;
    tempStruct.crowd = crowd;
    tempStruct.numbers = malloc(sizeof(*tempStruct.numbers)*crowd);
    return tempStruct;
}

int main(void) {
    magicNums myNumbers = makeStruct(10);
    free(myNumbers.numbers);
    return 0;
}
0

精彩评论

暂无评论...
验证码 换一张
取 消