【问题标题】:SIGTRAP when freeing a three dimensional array in C在 C 中释放三维数组时的 SIGTRAP
【发布时间】:2012-04-20 01:24:19
【问题描述】:

我正在尝试释放一个表示 bmp 图像的三维指针数组,并在它编译时确定我在调试时在 gdb 中收到 SIGTRAP 信号。我的错误信息是

警告:HEAP[bmpsample.exe]:
警告:0061FFB8 处的堆块在 0061FFCC 处修改,超过了请求的 c 大小。
程序收到信号 SIGTRAP,Trace/断点陷阱。 0x7787704e5 in ntdll!TpWaitForAlpcCompletion()
来自ntdll.dll

当我从 bmp 文件加载值后释放数组时发生错误。我的代码如下。

分配:

int ***alloc3D(int xlen, int ylen, int zlen) {
int i, j, ***array;
if ((array = malloc(xlen*sizeof(int**)))==NULL) {
    perror("Error in first assignment of 3D malloc\n");
}
// Allocate pointers for each row
for (i = 0; i < xlen; i++) {
    if ((array[i] = malloc(ylen*sizeof(int*)))==NULL){
        perror("Error in second assignment of 3D malloc\n");
    }
    // Allocate pointer for each column in the row
    for (j=0; j < ylen; j++) {
        if((array[i][j] = malloc(zlen*sizeof(int)))==NULL) {
            perror("Error in third assignment of 3D malloc\n");
        }
    }
}

填充数组

int ***readBitmap(FILE *inFile, BmpImageInfo info, int*** array) {
    // Pixels consist of unsigned char values red, green and blue
Rgb *pixel = malloc( sizeof(Rgb) );
int read, j, i;
for( j=0; j<info.height; j++ ) {
    read = 0;
    for( i=0; i<info.width; i++ ) {
        if( fread(&pixel, 1, sizeof(Rgb), inFile) != sizeof(Rgb) ) {
                printf( "Error reading pixel!\n" );
        }
        array[j][i][1] = (int)(pixel->red);
        array[j][i][2] = (int)(pixel->green);
        array[j][i][3] = (int)(pixel->blue);
        read += sizeof(Rgb);
    }

    if ( read % 4 != 0 ) {
        read = 4 - (read%4);
        printf( "Padding: %d bytes\n", read );
        fread( pixel, read, 1, inFile );
    }
}
free(pixel);

return array;

}

解除分配

void dealloc3D(int*** arr3D,int l,int m)
{
    int i,j;

    for(i=0;i<l;i++)
    {
        for(j=0;j<m;j++)
        {
                free(arr3D[i][j]);
        }
        free(arr3D[i]);
    }
    free(arr3D);
}

我怀疑问题在于将 RGB 值从 unsigned char 转换为 int,但我认为没有其他方法可以做到这一点。如果我只是将整数值分配给分配的数组,那么释放它们就没有问题。

【问题讨论】:

  • 你学会正确使用gdb了吗?当SIGTRAP 发生时,您是否要求回溯(使用gdbbt 命令)?你用gcc -Wall -g编译你的代码了吗?
  • 您正在破坏内存。将fread(&amp;pixel, 1, sizeof(Rgb), inFile) 更改为fread(pixel, 1, sizeof(*pixel), inFile),将read += sizeof(Rgb); 更改为read += sizeof(*pixel);。这样,当和/或pixel 的类型发生更改时,您的代码中需要更改的内容就会减少。
  • @BasileStarynkevitch 我正在使用-Wall-g 进行编译而没有错误,bt full 向我显示dealloc3D 是用数组的正确地址和正确的高度和宽度调用的。然而,我对 GDB 很陌生,我只知道最基本的控件。
  • @JimR 感谢您的建议,将 &pixel 更改为 pixel 并没有帮助。我还应该提到图像被正确读取到数组中(使用 Matlab 检查)。
  • 我真是个白痴。分配颜色值时,我从 1 开始索引。我的程序提供可读输出的唯一原因是因为我在稍后将图像转换为灰度的函数中执行完全相同的操作,这使我相信必须在释放中找到错误。很抱歉浪费了您的时间。

标签: c pointers multidimensional-array malloc free


【解决方案1】:

第一个fread 语句有问题

fread(&pixel, 1, sizeof(Rgb), inFile)

读入指针pixel,而不是读入pixel 指向的内容。之后,任何pixel 的使用都可能会破坏堆(或其他东西)。

【讨论】:

  • 谢谢。我已经实施了更改,但我仍然收到相同的错误消息,warning: HEAP[BMPSample.exe]: warning: Invalid address specified to RtlFreeHeap( 00940000, 00941C80 )warning: HEAP[BMPSample.exe]: warning: Heap block at 00941C78 modified at 00941C8C past requested size of c
  • 另一个潜在问题是array[j][i][3] 中的索引。根据Rgb 类型的外观,也许您应该使用索引 0、1 和 2 而不是 1、2 和 3?
  • 好的,谢谢博。我刚刚意识到这一点并对其进行了更改,现在它可以完美运行。我将其归咎于过于习惯于 Matlab 索引。
猜你喜欢
  • 2012-10-08
  • 2012-01-26
  • 1970-01-01
  • 2020-01-18
  • 2011-08-05
  • 1970-01-01
  • 1970-01-01
  • 2014-11-05
相关资源
最近更新 更多