Создание образа ядра в C освобождает ошибку памяти - PullRequest
0 голосов
/ 16 ноября 2018

Я пытаюсь создать ядро ​​фильтра Гаусса в C, чтобы выполнить некоторую обработку изображения.Я использую двумерный массив с плавающей точкой в ​​куче, но когда я вызываю free () для строк, я получаю ошибку free (): неверный указатель.Я распечатал ячейки памяти и значения фильтра на стандартный вывод, и все, кажется, то, что я ожидаю

//kernel->kernel = float **
//kernel->row_len = kernel->col_len = 5

float total_weight = 0.0;

//build the holding col
kernel->kernel = malloc(sizeof(float *) * kernel->col_len);
//get mem for each row and set the values
for (int j = 0; j < kernel->col_len; j++)
{
    kernel->kernel[j] = malloc(sizeof(float) * kernel->row_len);
    for (int i = 0; i < kernel->row_len; i++)
    {
        kernel->kernel[j][i] = ken_ComputeGuassianVal(i, j, sigma, size);
        total_weight += kernel->kernel[j][i];
    }
    //print debugging info
    printf("Create - %p\n", (kernel->kernel + j));
    for (int i = 0; i < kernel->row_len; i++)
    {
        printf("%d, %d - %f \n", i, j, kernel->kernel[j][i]);
        printf("%p\n", (*(kernel->kernel + j) + i));
    }
    printf("\n");
}

//Normalise the kernel otherwise brightness will be added to the image
for (int j = 0; j < kernel->col_len; j++)
{
    for (int i = 0; i < kernel->row_len; i++)
    {
        kernel->kernel[j][i] /= total_weight;
    }
}
for (int j = 0; j < kernel->col_len; j++)
{
    printf("Attempting to free memory at location %p\n", (kernel->kernel + j));
    free(kernel->kernel + j);
    printf("\n");
}
free(kernel->kernel);

Вот вывод, который я получаю на стандартный вывод

Create - 0x55aa2a80d4e0
0, 0 - 0.000000
0x55aa2a7ed8d0
1, 0 - 0.000000
0x55aa2a7ed8d4
2, 0 - 0.000001
0x55aa2a7ed8d8
3, 0 - 0.000000
0x55aa2a7ed8dc
4, 0 - 0.000000
0x55aa2a7ed8e0

Create - 0x55aa2a80d4e8
0, 1 - 0.000000
0x55aa2a84c6a0
1, 1 - 0.001083
0x55aa2a84c6a4
2, 1 - 0.034551
0x55aa2a84c6a8
3, 1 - 0.001083
0x55aa2a84c6ac
4, 1 - 0.000000
0x55aa2a84c6b0

Create - 0x55aa2a80d4f0
0, 2 - 0.000001
0x55aa2a7f96a0
1, 2 - 0.034551
0x55aa2a7f96a4
2, 2 - 1.102181
0x55aa2a7f96a8
3, 2 - 0.034551
0x55aa2a7f96ac
4, 2 - 0.000001
0x55aa2a7f96b0

Create - 0x55aa2a80d4f8
0, 3 - 0.000000
0x55aa2a80d510
1, 3 - 0.001083
0x55aa2a80d514
2, 3 - 0.034551
0x55aa2a80d518
3, 3 - 0.001083
0x55aa2a80d51c
4, 3 - 0.000000
0x55aa2a80d520

Create - 0x55aa2a80d500
0, 4 - 0.000000
0x55aa2a7eddf0
1, 4 - 0.000000
0x55aa2a7eddf4
2, 4 - 0.000001
0x55aa2a7eddf8
3, 4 - 0.000000
0x55aa2a7eddfc
4, 4 - 0.000000
0x55aa2a7ede00

Destroy - 0x55aa2a7ed8d0
Attempting to free memory at location 0x55aa2a80d4e0

Destroy - 0x55aa2a84c6a0
Attempting to free memory at location 0x55aa2a80d4e8
free(): invalid pointer
[1]    13936 abort      ./dipcw

Я пробовал и обозначение массива kernel-> kernel [j] и (kernel-> kernel + j).Я использую элементарный linux 5.0 и gcc версии 7.3.0 (Ubuntu 7.3.0-27ubuntu1 ~ 18.04)

Редактировать: Изменена переменная условия остановки в цикле нормализации для использования тех же переменных, что и в других циклах.Добавлен бесплатный оператор для двойного указателя в конце

1 Ответ

0 голосов
/ 16 ноября 2018

Правило: для каждого malloc()


struct matrix {
        unsigned nrow;
        unsigned ncol;
        float ** ptrs;
        } data;

/* allocate */

unsigned row, col;

data.ptrs = malloc (data.nrow * sizeof *data.ptrs);                 // <<< [A]
for (row=0; row < data.nrow; row++) {                               // <<< [B]
        data.ptrs[row] = malloc (data.ncol * sizeof *data.ptrs[0]); // <<< [C]
        }


/* there should be a corresponding free for every malloc
   , but in the "inside-out" order :
 */

unsigned row, col;

for (row=0; row < data.nrow; row++) {     // <<< [B]
        free( data.ptrs[row] );           // <<< [C]
        }

free(data.ptrs);                          // <<< [A]

должно быть соответствующее free() Примечание: для простоты я поменял местами строки / столбцы и использовал matrix.field вместо pointer->field.

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