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

C程序在Cygwin中运行,但不在Linux(Malloc)中运行,c,gdb,malloc,valgrind,C,Gdb,Malloc,Valgrind,我在代码中发现了一个堆分配错误,该错误是在Linux上的vanguard/gdb上发现的,但在Windows cygwin环境中运行良好。我知道Linux的堆分配可能比Windows更严格,但我真的希望有一个发现问题/可能修复的响应。我也知道我不应该在C中输入malloc,但这是一种习惯,不会改变我的问题。实际上,我的程序在Linux和Windows上编译都没有错误,但当我在Linux上运行它时,我得到了一个可怕的结果: malloc.c:3074:sYSMALLOc:Assertion`(ol

我在代码中发现了一个堆分配错误,该错误是在Linux上的vanguard/gdb上发现的,但在Windows cygwin环境中运行良好。我知道Linux的堆分配可能比Windows更严格,但我真的希望有一个发现问题/可能修复的响应。我也知道我不应该在C中输入malloc,但这是一种习惯,不会改变我的问题。实际上,我的程序在Linux和Windows上编译都没有错误,但当我在Linux上运行它时,我得到了一个可怕的结果:

malloc.c:3074:sYSMALLOc:Assertion`(old_top==((mbinptr)((char*)和((av)->bins[((1)-1)*2])-(struct malloc_chunk,fd))和old_size==0)(无符号长)(old_size)>=(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)和无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)(无符号长)和长尺寸)(无符号长)(无符号长)(无符号长尺寸)(无符号长尺寸)(无符号长尺寸)(无符号长尺寸)(无符号长尺寸)(无符号((旧_-top)->size&0x1)&((无符号长)旧_-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;
}
/*Main*/
int main(int argc,char*argv[]){
文件*pFile;
无符号字符*缓冲区;
长时间集成;
pFile=fopen(argv[1],“r”);
如果(pFile==NULL){fputs(“arg[1]上的文件错误”,stderr);返回1;}
fseek(pFile,0,SEEK_END);
lSize=ftell(pFile);
倒带(pFile);
缓冲区=(char*)malloc(sizeof(char)*lSize+1);
if(buffer==NULL){fputs(“内存错误”,stderr);返回2;}
比特对*ppairs=(比特对*)malloc(sizeof(比特对)*(lSize+1));
//下面第51行
calcpair(ppairs,(lSize+1));
/*无关的东西*/
fclose(pFile);
自由(缓冲);
免费(ppairs);
}
类型定义结构{
长无符号int a;//不是实际的变量名……是的,我需要它们是长无符号的
长无符号整数b;
长无符号整数c;
长无符号整数d;
长无符号整数e;
}位对;
void calcpair(位对*ppair,长整数位);
void calcPairs(位对*ppairs,长整数位){
长int i,top,bot,var_1,var_2;
整数计数=0;
对于(i=0;ia=var_2;
bp->b=var_1;
bp->c=i;
bp=&ppairs[var_1];
bp->a=var_2;
bp->b=var_1;
bp->c=i;
}
返回;
}
gdb报告:free():无效指针:0x0000000000603290*

由于“valgrind内部错误”信号11(SIGSEGV),valgrind在退出之前报告以下消息5次:
大小为8的读取无效
==2727==0x401043:calcPairs(在/home/user/Documents/5-3/ubuntu test/main中)
==2727==0x400C9A:main(main.c:51)

==2727==地址0x5a607a0不是堆栈、malloc或(最近)free'd

随意猜测ftell返回-1,malloc不喜欢被要求分配零字节。malloc的行为(0)在C中是否依赖于实现。

malloc
的第二次调用从未检查其返回值。请修改它,使其看起来更像第一次调用,如:

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

另外,请记住
malloc
要求参数使用
size\u t
(其定义取决于实现)。请确保在将
(sizeof(位对)*(lSize+1))
传递给
malloc
时,不会溢出
size\u t
(如果
size\u t
被定义为
unsigned int
,您可能会遇到问题,因为
lSize
是一个
long
)。

看起来您希望malloc返回预调零内存

    do {
        bot = count;
        count++;
    } while(ppairs[bot].e != 0);
可以很容易地结束您的ppairs,而无需找到归零的ppairs[bot].e

您希望使用calloc而不是malloc,这将在返回内存之前清除内存

bitpair * ppairs = (bitpair *) calloc(sizeof(bitpair) * (lSize+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)); 
do{
bot=计数;
计数++;
}而((bot
你的,
Tom

我想你漏掉了有趣的部分..calcpair()中发生了什么?谢谢你的评论,我已经更新了OP,包含了calcpair()的片段。“buffer”用于在第二个文件上执行迭代fread,每次执行一个字节:fread(buffer,1,1,pFile);对不起,迭代fread在OP中打开的同一个文件上(pFile).这是您完整的
calcPairs
函数还是仅仅是一个片段?如果这是全部,那么您有几个问题,其中最重要的是
do{…}而
loop能够运行到阵列的末尾。如果您需要诊断帮助,请将整个源代码放在一个网站上并链接到它。如果您没有自己的网站,这是一个好地方(但不是存档)。我可以通过测试确认lSize的大小是正确的,在本例中为27(有时要大得多,因此需要很长时间)。它依赖于实现,但它必须返回一个指针值,您可以安全地传递给
free()
(包括
NULL
)。不允许中止。谢谢,我确实忘记了这么做。不幸的是,malloc问题仍然存在,将函数中的lSize和相关变量更改为正则int导致了相同的运行时错误随机想法(可能会更改,也可能不会更改任何内容):不要在调用
malloc
的同一行中声明
ppairs
,而是在函数顶部声明它。另外,尝试将
位对的定义向上移动到
函数上方。尽管没有正确调用calloc(需要两个参数),但这很有帮助:void*calloc(size\t