【问题标题】:Create image kernel in C freeing memory error在 C 中创建图像内核释放内存错误
【发布时间】:2018-11-16 11:59:39
【问题描述】:

我正在尝试在 C 中创建一个高斯滤波器内核来进行一些图像处理。我在堆上使用 2d 浮点数组,但是当我在行上调用 free() 时,我不断收到 free(): invalid pointer 错误。我已将过滤器的内存位置和值打印到标准输出,一切似乎都是我所期望的

//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)

编辑:更改了规范化循环中的停止条件变量,以使用与其他循环相同的变量。在末尾添加了双指针的free语句

【问题讨论】:

  • 您的“规范化内核”循环不使用与其他循环相同的大小。 size 是否等于 kernel-&gt;col_lenkernel-&gt;row_len
  • size 等于他们两个,抱歉是因为我剪掉了一些与我的问题无关的功能
  • free(kernel-&gt;kernel + j); -->> 你可能想要free(kernel-&gt;kernel[ j] );(虽然你也需要 master 指针数组)
  • @joop 当我更改为 free 时,我在 j = 0 的第一个循环条件上得到一个无效指针
  • 它们在我创建的示例代码中,我的实际代码最初在一个单独的函数中具有 free 但当它不起作用时,我将它移到 malloc 函数中进行调试跨度>

标签: c pointers


【解决方案1】:

规则是:每个malloc()都应该有一个对应的free()


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]

注意:为简单起见,我交换了行/列,并使用 matrix.field 而不是 pointer-&gt;field

【讨论】:

  • 我想不是吗?我分配浮点指针数组kernel-&gt;kernel = malloc(sizeof(float *) * kernel-&gt;col_len); 并释放它们free(kernel-&gt;kernel); 我还有两组相同迭代计数的循环来malloc 或释放浮点数组
  • 是的,但是您在 free() 调用中的指针运算不正确。 free() 的参数应该等同于您从以下位置获得的 lval:lval = malloc(...)。 (你省略了一级间接)
  • 好的,我从理论上理解,谢谢。但是在这种情况下,我的免费代码应该是什么?
  • free(kernel-&gt;kernel[j]); 正如我在评论中所说。这与您的第一个循环顶部的kernel-&gt;kernel[j] = malloc(...) 匹配。
  • 当我更改为free(kernel-&gt;kernel[j]); 时,我回复了您之前的评论,它也不起作用。在我最初的问题中说我尝试了两种语法。我的输出结束了Destroy - 0x55a7d545f8d0 Attempting to free memory at location 0x55a7d547f4e0 free(): invalid pointer [1] 15530 abort ./dipcw
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2015-06-21
  • 1970-01-01
  • 1970-01-01
  • 2014-12-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多