C程序在Cygwin中运行,但不在Linux(Malloc)中运行
我在代码中发现了一个堆分配错误,该错误是在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)失败。 流产 我的代码中附加的代码段被指出为错误以供审阅: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
/* 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