Как правильно освободить при ошибке выделения памяти для двумерного массива - PullRequest
0 голосов
/ 24 апреля 2018

Я столкнулся с чем-то странным при освобождении памяти в двумерном массиве после того, как что-то пошло не так.

Дело 1:

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

int main(void)
{
    int **a = NULL;
    int i;
    int j;

    if(!(a = calloc(5, sizeof(int *))))
    {
        printf("Error, could not allocate memory for a!\n");
        exit(EXIT_FAILURE);
    }

    for(i = 0; i < 5; i++)
    {
        if(i != 2)
        {
            if(!(a[i] = calloc(3, sizeof(int))))
            {
                printf("Error, could not allocate memory for a[%d]!\n",i);
                for(j = 0; j < i; j++)
                {
                    free(a[j]);
                }
                free(a);
            }
        }

        else
        {
            if(!(a[i] = calloc(MAX_INT * 1000, sizeof(int))))
            {
                printf("Error, could not allocate memory for a[%d]\n", i);
                for(j = 0; j < i; j++)
                {
                    free(a[j]);
                }
                free(a);
            }
        }
    }

    return 0;
}

Случай 2:

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

int main(void)
{
    int **a = NULL;
    int i;
    int j;

    if(!(a = calloc(5, sizeof(int *))))
    {
        printf("Error, could not allocate memory for a!\n");
        exit(EXIT_FAILURE);
    }

    for(i = 0; i < 5; i++)
    {
        if(i != 2)
        {
            if(!(a[i] = calloc(3, sizeof(int))))
            {
                printf("Error, could not allocate memory for a[%d]!\n",i);
                for(j = 0; j <= i; j++)
                {
                    free(a[j]);
                }
                free(a);
            }
        }

        else
        {
            if(!(a[i] = calloc(MAX_INT * 1000, sizeof(int))))
            {
                printf("Error, could not allocate memory for a[%d]\n", i);
                for(j = 0; j <= i; j++)
                {
                    free(a[j]);
                }
                free(a);
            }
        }
    }

    return 0;
}

Единственное различие между этими двумя случаями состоит в том, что в случае 1, когда что-то идет не так, выделяя память (у меня сознательно есть большое выделение, чтобы вызвать его сбой при i == 2), я зацикливаюсь от j = 0 до j

1 Ответ

0 голосов
/ 24 апреля 2018

Для входа в ветку if с ошибочным распределением a[i] должен быть установлен в указатель NULL. Поскольку передача указателя NULL на free четко определена в стандарте C , включение или исключение a[i] в цикле не имеет значения.

Обе версии имеют одну и ту же проблемутем не менее: когда сбой происходит во внешнем цикле for, вы не выходите из программы после очистки, позволяя продолжить выделение.Это должно быть исправлено добавлением вызова к exit(EXIT_FAILURE) после free(a).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...