1

我有一个堆分配错误,我无法在我的代码中发现该错误,该错误在 Linux 上的 vanguard/gdb 上被拾取,但在 Windows cygwin 环境中完美运行。我知道 Linux 的堆分配可能比 Windows 更严格,但我真的很想得到一个发现问题/可能修复的回应。我也知道我不应该在 C 中对 malloc 进行类型转换,但这是一种习惯的力量,不会改变我的问题的发生。我的程序实际上在 Linux 和 Windows 上都没有错误地编译,但是当我在 Linux 中运行它时,我得到了一个看起来很吓人的结果:

malloc.c:3074: sSYSMALLOc: 断言`(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) || ((unsigned long) (old_size) >= (unsigned long)((((__builtin_offsetof (struct malloc_chunk, fd_nextsize))+((2 * (sizeof(size_t))) - 1)) & ~((2 * (sizeof (size_t))) - 1))) && ((old_top)->size & 0x1) && ((unsigned long)old_end & pagemask) == 0)' 失败。中止

我的代码中的附加片段被指出为审查错误:

/* Main */

int main(int argc, char * argv[]) {

    FILE *pFile;  
    unsigned char *buffer;  
    long int lSize;  

    pFile = fopen ( argv[1] , "r" );
    if (pFile==NULL) {fputs ("File error on arg[1]",stderr); return 1;}

    fseek (pFile , 0 , SEEK_END);
    lSize = ftell (pFile);
    rewind (pFile);

    buffer = (char*) malloc(sizeof(char) * lSize+1);
    if (buffer == NULL) {fputs ("Memory error",stderr); return 2;}

    bitpair * ppairs = (bitpair *) malloc(sizeof(bitpair) * (lSize+1));

    //line 51 below
    calcpair(ppairs, (lSize+1));

    /* irrelevant stuff */

    fclose(pFile);
    free(buffer);
    free(ppairs);  
}

typedef struct {  
long unsigned int a;  //not actual variable names...  Yes I need them to be long unsigned  
long unsigned int b;  
long unsigned int c;  
long unsigned int d;  
long unsigned int e;  
} bitpair;  

void calcpair(bitpair * ppairs, long int bits);

void calcPairs(bitpair * ppairs, long int bits) {

    long int i, top, bot, var_1, var_2;
    int count = 0;

    for(i = 0; i < bits; i++) {

        top = 0;

        ppairs[top].e = 1;

        do {
            bot = count;
            count++;
        } while(ppairs[bot].e != 0);

        ppairs[bot].e = 1;

        var_1 = bot;
        var_2 = top;

        bitpair * bp = &ppairs[var_2];
        bp->a = var_2;
        bp->b = var_1;
        bp->c = i;

        bp = &ppairs[var_1];
        bp->a = var_2;
        bp->b = var_1;
        bp->c = i;

    }

    return;
}

gdb 报告:free():无效指针:0x0000000000603290 *

由于“VALGRIND INTERNAL ERROR”信号 11 (SIGSEGV),valgrind 在退出前 5 次报告以下消息:在 0x401043 处
读取大小为 8
==2727== 的无效:calcPairs (in /home/user/Documents/5-3/ubuntu test/main)
==2727== by 0x400C9A: main (main.c:51)
==2727== Address 0x5a607a0 is not stack'd, malloc'd or (recently) free'd

4

4 回答 4

1

在一个疯狂的猜测 ftell 返回 -1 并且 malloc 不喜欢被要求分配零字节。malloc(0) 的行为取决于 C 中的实现。

于 2010-05-04T16:09:00.333 回答
1

看起来像数组溢出

没有什么能阻止这个循环超出 ppair 数组的末尾:

    do { 
        bot = count; 
        count++; 
    } while(ppairs[bot].e != 0); 

特别是因为此行将覆盖您的终止零:

ppairs[bot].e = 1;

试试这个:

    do { 
        bot = count; 
        count++; 
    } while((bot < bits) && (ppairs[bot].e != 0)); 

你的,汤姆

于 2010-05-08T00:13:40.933 回答
1

看起来您希望 malloc 返回预置零的内存。

    do {
        bot = count;
        count++;
    } while(ppairs[bot].e != 0);

无需找到归零的 ppairs[bot].e 即可轻松结束您的 ppairs

您想使用 calloc 而不是 malloc,这会在返回之前清除内存。

bitpair * ppairs = (bitpair *) calloc(sizeof(bitpair) * (lSize+1));
于 2010-05-04T17:09:49.843 回答
0

您的第二次调用mallocnever 检查其返回值。修改它,使它看起来更像第一个,如下所示:

bitpair * ppairs = (bitpair *) malloc(sizeof(bitpair) * (lSize+1));
if (ppairs == NULL) {fputs ("Memory error",stderr); free(buffer); return 3;}

另外,请记住,参数malloc需要一个size_t(其定义取决于实现)。确保当你传递(sizeof(bitpair) * (lSize+1))到时malloc,你没有溢出 a size_t(如果size_t定义为unsigned int,你可能会遇到问题,因为lSize是 a long)。

于 2010-05-04T16:57:48.347 回答