@NaName

Почему free() срабатывает только один раз?

Есть такой код на Си:

SIZE_J = 100500 - максимально возможный размер массива данных

void getDataFromFile(char *file_name, double *edmaxlat, double *edmaxlon, double latitude[], double longitude[], int *size) {
    int nc_file_id;
    int retval;
    int GEO_lat_id, GEO_lon_id;
    double *latitude_buffer = (double*)malloc(sizeof(double)*SIZE_J);
    double *longitude_buffer = (double*)malloc(sizeof(double)*SIZE_J);

    открыл файл
    if ((retval = nc_open(file_name, NC_NOWRITE, &nc_file_id)))
        ERR(retval);

    узнал ID переменных с нужными именами
    if ((retval = nc_inq_varid(nc_file_id, "GEO_lat", &GEO_lat_id)))
        ERR(retval);
    if ((retval = nc_inq_varid(nc_file_id, "GEO_lon", &GEO_lon_id)))
        ERR(retval);

    читаю переменные из файла по их ID
    if ((retval = nc_get_var_double(nc_file_id, GEO_lat_id, &latitude_buffer[0])))
        ERR(retval);
    if ((retval = nc_get_var_double(nc_file_id, GEO_lon_id, &longitude_buffer[0])))
        ERR(retval);

    for (int j = 0; j < SIZE_J; j++) {
        эти две переменные не нужны, использовал для принтов в цикле
        latitude[j] = latitude_buffer[j];
        longitude[j] = longitude_buffer[j];

        запоминаю размер массива. используется в других функциях
        if (height[j] <= 0.000000000001) {
            *size = j;
            break;
        }

    }
    free(latitude_buffer);
    free(longitude_buffer);

При работе этой функции в цикле без free(), latitude_buffer и longitude_buffer запоминают значения предыдущих итераций. Т.е. например в первой итерации было 10 элементов в буфере, во второй итерации 5 элементов в буфере (входные данные), тогда во второй итерации в переменной latitude будет 10 элементов. Не знаю почему так получается поэтому попробовал использовать free(). Но с free() тоже проблема. Если вызывать free() только один раз, например закомментировать второй вызов, то всё ок. Т.е. latitude всегда хранит адекватные значения, но longitude попрежнему переполняется (?). Если закомментировать первый вызов то тоже все ок. longitude хранит адекватные значения а latitude переполняется (?). Проблема в том что если оставить оба вызова, как в примере кода выше, то выполняется только первый free(), как-будто второй вызов закомментирован. Почему так происходит? Как сделать чтобы чистились оба буфера, или как сделать чтобы оба буфера не надо было чистить, но можно было сделать их переменной размерности? Да, в Си я очень плохо разбираюсь.
  • Вопрос задан
  • 172 просмотра
Пригласить эксперта
Ответы на вопрос 2
zagayevskiy
@zagayevskiy
Android developer at Yandex
В каком смысле "буферы переполняются"? У вас буферы - это просто указатели на область памяти, в целом вы можете хоть до потери пульса по ним итерироваться.
И потом, malloc отдаёт вам неинициализированную память, то есть там просто мусор. Не вижу, чтобы вы как-либо инициализирвали их. Используйте memset, например.

дальше, free это правильно. Надо делать free всегда, когда вы делаете malloc.
Ответ написан
@Mercury13
Программист на «си с крестами» и не только
Переполняется longitude, говорите? Ну убедитесь, что он размера SIZE_J. Не этой функции, правда, дело.
Кроме того, вы массивы latitude[] и longitude[] заполняете случайным мусором, появившимся в результате malloc.
Ответ написан
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы