C: Как освободить память для структурирования, когда на нее больше нет указателя? - PullRequest
1 голос
/ 08 февраля 2011

У меня есть функция, которая создает структуру и возвращает саму новую структуру. Структура содержит массив чисел и целое число, показывающее, сколько чисел существует (это работает как массив). Итак, у меня есть makeStruct, который создает временную структуру и затем возвращает ее. В основном я вызываю эту функцию и присваиваю ее структуре myNumbers. Это приводит к тому, что в функции создается экземпляр структуры, копируется в myNumbers, а затем удаляется. Правильно ли мое предположение?

Это, кажется, компилируется правильно, но я не вижу способа освободить выделенную память, так как нет указателя, указывающего на мою структуру. Как мне освободить память?

#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;
}

Ответы [ 9 ]

4 голосов
/ 08 февраля 2011

Что касается ответа на ваш вопрос: «Как освободить память для структурирования, когда на нее больше нет указателя?».

Ты не можешь. Ваш код утечки памяти.

Однако в вашем коде много ошибок, которые не имеют смысла

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

Первые две строки сначала устанавливают struct_ptr = & tempStruct; , а затем заменяет этот указатель на возврат из malloc. 2 строки выполняют точно так же, как:

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

Это может прояснить, что происходит.

return tempStruct;

Возвращая tempStruct здесь, вы потеряли указатель на struct_ptr, поэтому вы не можете его освободить, и вы теряете память.

Вы не потеряли указатель на tempStruct.numbers. Вы можете освободить это в своей главной:

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

magicNums не является указателем, вы не можете и не должны освобождать это. Вы возвращаете структуру по значению, так что все в порядке - там нет динамической памяти.

2 голосов
/ 08 февраля 2011

Это правильно, вы не можете освободить память, так как у вас нет действительного указателя на нее. Вы успешно создали утечку памяти.

Вам нужно будет возвращать указатель структуры из этой функции, а не структуру по значению.

Почему вы используете для этого malloc ()?

1 голос
/ 08 февраля 2011

Вам не нужно выделять память для самой структуры, ваш makeStruct должен выглядеть следующим образом:

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

Хотя tempStruct создается в стеке и автоматически освобождается при возврате функции, функция создаст копию tempStruct и вернет ее.

тогда вы можете использовать это так:

int main() {
    magicNums myNumbers;
    myNumbers = makeStruct(10);
    free(myNumbers.numbers);
}
1 голос
/ 08 февраля 2011

Здесь много проблем.С одной стороны, ответить на вопрос - вы не можете.Но это не совсем ваша проблема здесь:

Я собираюсь предположить, что вы хотите это вместо этого:

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;
}

Тогда main будет

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

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

    return 0;
}
1 голос
/ 08 февраля 2011

Попробуйте вместо этого вернуть указатель.

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;
}
0 голосов
/ 08 февраля 2011

Вот код, который соответствует вашему описанию того, что, по вашему мнению, вы делаете.Это то, что вы хотите сделать, я не знаю.

#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 голосов
/ 08 февраля 2011

Вы можете выполнить очистку в самой функции, возвращая копию структуры в основную программу.Затем у вас будет ссылка на эту копию, и вы сможете освободить ее после использования, чтобы освободить память.

Редактировать: см. Ответ Мартинса, который может быть именно тем, что вы хотите:

0 голосов
/ 08 февраля 2011

Насколько я понимаю, вам просто не нужны первые malloc внутри makeStruct.

Тогда позже в вашем int main(void) (!) Вы можете сделать

free(myNumbers.numbers);
0 голосов
/ 08 февраля 2011

Как освободить память для структурирования, когда на нее больше нет указателя?

Удачи с этим!Если вы не знаете, где это, как вы можете надеяться освободить его?Решение: запомни, куда ты его положил!

...