0

Я ищу наиболее удобный/лучший/умный способ для освобождения памяти. Не совсем уверен, что это лучшее объяснение там, но вот пример, который покажет, что я хочу сделать:Самый удобный способ освободить несколько указателей памяти?

void func() 
{ 
    int* ptr1 = malloc(1); 
    if(ptr1 == NULL) 
    { 
     //... 
    } 

    int* ptr2 = malloc(1); 
    if(ptr2 == NULL) 
    { 
     //... 
     free(ptr1); 
    } 

    int* ptr3 = malloc(1); 
    if(ptr3 == NULL) 
    { 
     //... 
     free(ptr2); 
     free(ptr1); 
    } 

    //code... 
} 

Единственное, что приходит на ум это массив заполнен флагами, если флаг повышенная определенная память должна быть освобождена. Есть ли еще более удобный способ сделать это? Вы можете себе представить, сколько раз мне нужно повторить free(), если есть необходимость в более malloc() -е.

+1

поместить их в массив, который является NULL завершение/инициализация и повторение этого массива. –

+0

Я надеюсь, что есть другой способ сделать это, кроме использования массива. –

+1

'ptr1 * = malloc (1);' полная чушь. пожалуйста, напишите реальный код. – joop

ответ

3

Что вы вывесили является обычной практикой для обработки ошибок и выпуска ресурсов в функции, вы получаете несколько ресурсов, и в случае, если какая-либо ошибка произошло, вам нужно освободить те, которые были приобретены ранее, нет ничего плохого, просто сделайте это один за другим.

void func(void) { 
    void *ptr1 = NULL; 
    void *ptr2 = NULL; 
    void *ptr3 = NULL; 

    ptr1 = malloc(SIZE); 
    if (!ptr1) goto end; 

    ptr2 = malloc(SIZE); 
    if (!ptr2) goto end; 

    ptr3 = malloc(SIZE); 
    if (!ptr3) goto end; 

    // do your work with the buffers 

end: 
    free(ptr1); 
    free(ptr2); 
    free(ptr3); 
} 
+0

@ user694733, что заставило бы код зависеть от поведения (реализации) 'free', чтобы не сбой при освобождении указателя NULL. Я согласен с оригинальным, защитным и правильным подходом к тестированию ptr для NULL, прежде чем звонить бесплатно. –

+1

Стандарт @PaulOgilvie C (из черновика N1570) в главе 7.22.3.3 гласит: * «Свободная функция заставляет освободить пространство, на которое указывает ptr, то есть сделать доступным для дальнейшего размещения. Если ptr является нулевым указателем, нет действие бывает. ... "* – user694733

+0

@ пользователь694733, стандарты изменение. У прошлых стандартов этого не было. Код не защищен. Это вызывает потенциально ненужные вызовы функций. Мой аргумент, возможно, основан на мнениях. –

3

Вы можете использовать array of pointers и продолжать отсчет количества выполненных malloc. И используйте общую бесплатную функцию для всех free. Мол,

void func() 
{ 
    char* ptr[10]; 
    int n = 0, i; 

    for(i = 0; i < 10; i++) 
     ptr[i] = NULL; 

    ptr[n] = malloc(1); 
    if(ptr[n] == NULL) 
    { 
     //... 
    } 
    n++; 

    ptr[n] = malloc(1); 
    if(ptr[n] == NULL) 
    { 
     //... 
     custom_free(ptr1, n); 
    } 
    n++; 

    ptr[n] = malloc(1); 
    if(ptr[n] == NULL) 
    { 
     //... 
     custom_free(ptr, n); 
    } 
    n++; 
    //code... 
} 

И custom_free() может быть что-то подобное,

void custom_free(char* ptr[], int n) 
{ 
    int i; 

    for(i = 0; i <= n; i++) 
     free(ptr[i]); 
} 
0

Альтернативный способ выделить всю необходимую память в один большой кусок, и лечить ЧАСТЕЙ о том, что, как p0, p1, p2:

void worker(void) 
{ 
#define N_ELEM 123 
int *work_mem; 
int *p0,*p1,*p2; 

work_mem = malloc (3* N_ELEM * sizeof *work_mem); 
if (!work_mem) { OMG(); return; } 

p0 = work_mem, p1= work_mem + N_ELEM, p2 = work_mem + 2 * N_ELEM; 

     /* do useful stuff here with work_mem 
     ** , possibly via p0,p1,p2 
     */ 

free(work_mem); 
} 
+0

Хотя это может сработать, вы должны вручную убедиться, что все указатели правильно выровнены. Было бы безопаснее разместить все переменные в единой структуре и позволить компилятору сортировать детали юстировки. – user694733

+0

Да, но вам придется позаботиться о правильности и в оригинальном случае. ['int * p = malloc (1);' в (исправленном) вопросе не подходит для даже хранения одного int, например] – joop

+0

Правда, но это проблема с размером, а не выравниванием. Но даже проблема с размерами проще обрабатывать со структурой, предполагая, что требуемый размер является статичным, как в вашем примере: 'CombinedType * data = malloc (sizeof * data);' – user694733

Смежные вопросы