C程序在Cygwin中运行但不在Linux中运行(Malloc)

时间:2010-05-04 16:02:52

标签: c gdb malloc valgrind

我有一个堆分配错误,我无法在我的代码中发现它在Linux上的vanguard / gdb上获取但在Windows cygwin环境中运行完美。我知道Linux的堆分配可能比Windows更紧,但我真的希望有一个响应来发现问题/可能的修复。我也知道我不应该在C语言中使用malloc,但这是一种习惯的力量,并不会改变我的问题。我的程序实际上在Linux和Linux上编译时没有错误。 Windows,但是当我在Linux中运行它时,我得到一个可怕的结果:

  

malloc.c:3074:sYSMALLOc:断言`(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次:
读取大小为8的无效 == 2727 ==在0x401043:calcPairs(在/ home / user / Documents / 5-3 / ubuntu test / main)
== 2727 == by 0x400C9A:main(main.c:51)
== 2727 ==地址0x5a607a0没有堆叠,malloc'd或(最近)免费

4 个答案:

答案 0 :(得分:1)

疯狂猜测ftell返回-1并且malloc不喜欢被要求分配零字节。 malloc(0)的行为是依赖于C的实现。

答案 1 :(得分:1)

看起来你期望malloc返回预先归零的内存。

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

可以很容易地找到你的ppairs的结尾,而没有找到一个零的ppairs [bot] .e

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

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

答案 2 :(得分: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)); 

此致, 汤姆

答案 3 :(得分:0)

您对malloc的第二次调用永远不会检查其返回值。修改它使它看起来更像第一个,如:

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时,您没有溢出size_t(如果size_t定义为unsigned int,您可能会遇到问题,因为lSizelong)。