[英]C program runs in Cygwin but not Linux (Malloc)
I have a heap allocation error that I cant spot in my code that is picked up on vanguard/gdb on Linux but runs perfectly on a Windows cygwin environment. 我有一个堆分配错误,我无法在我的代码中发现该错误,该错误在Linux的vanguard / gdb上被发现,但是可以在Windows cygwin环境下完美运行。 I understand that Linux could be tighter with its heap allocation than Windows but I would really like to have a response that discovers the issue/possible fix.
我知道Linux的堆分配可能比Windows更严格,但是我真的很想得到一个发现问题/可能的解决方法的响应。 I'm also aware that I shouldn't typecast malloc in C but it's a force of habit and doesn't change my problem from happening.
我也意识到我不应该在C中强制转换malloc,但这是一种习惯,不会改变我的问题。 My program actually compiles without error on both Linux & Windows but when I run it in Linux I get a scary looking result:
我的程序实际上在Linux和Windows上都可以正确编译,但是当我在Linux上运行时,我得到的结果看起来很恐怖:
malloc.c:3074: sYSMALLOc: Assertion `(old_top == (((mbinptr) (((char *) &((av)->bins[((1) - 1) * 2])) - __builtin_offsetof (struct malloc_chunk, fd)))) && old_size == 0) ||
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)' failed.
(((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)'失败。 Aborted
中止
Attached snippet from my code that is being pointed to as the error for review: 我的代码所附的片段被指出为要检查的错误:
/* 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 reports: free(): invalid pointer: 0x0000000000603290 * gdb报告:free():无效的指针:0x0000000000603290 *
valgrind reports the following message 5 times before exiting due to "VALGRIND INTERNAL ERROR" signal 11 (SIGSEGV): 由于“ VALGRIND INTERNAL ERROR”信号11(SIGSEGV),valgrind在退出前报告了5次以下消息:
Invalid read of size 8 大小为8的读取无效
==2727== at 0x401043: calcPairs (in /home/user/Documents/5-3/ubuntu test/main) == 2727 ==在0x401043:calcPairs(在/ home / user / Documents / 5-3 / ubuntu test / main中)
==2727== by 0x400C9A: main (main.c:51) == 2727 ==通过0x400C9A:main(main.c:51)
==2727== Address 0x5a607a0 is not stack'd, malloc'd or (recently) free'd == 2727 ==地址0x5a607a0未堆栈,未分配或(最近)释放
At a wild guess ftell is returning -1 and malloc doesn't like being asked to allocate zero bytes. 毫无疑问,ftell返回-1,而malloc不喜欢被要求分配零字节。 The behaviour of malloc(0) is implementation dependent in C.
malloc(0)的行为取决于C中的实现。
It looks like you are expecting malloc to return pre-zeroed memory. 看起来您期望malloc返回预调零的内存。
do {
bot = count;
count++;
} while(ppairs[bot].e != 0);
could easily get to the end of your ppairs without finding a zeroed ppairs[bot].e 可以轻松找到您的配对的结尾,而无需找到零配对[bot] .e
You want to use calloc instead of malloc, that clears the memory before returning it. 您想使用calloc而不是malloc,在返回内存之前先清除内存。
bitpair * ppairs = (bitpair *) calloc(sizeof(bitpair) * (lSize+1));
Nothing is keeping this loop from overrunning the end of the ppair array: 没有什么可以阻止此循环越过ppair数组的末尾:
do {
bot = count;
count++;
} while(ppairs[bot].e != 0);
Especially since this line will overwrite your terminating zero: 特别是由于此行将覆盖终止的零:
ppairs[bot].e = 1;
Try this instead: 尝试以下方法:
do {
bot = count;
count++;
} while((bot < bits) && (ppairs[bot].e != 0));
Yours, Tom 你的,汤姆
Your second call to malloc
never has its return value checked. 您对
malloc
第二次调用永远不会检查其返回值。 Modify it so it looks more like the first one, as in: 对其进行修改,使其看起来更像第一个,如:
bitpair * ppairs = (bitpair *) malloc(sizeof(bitpair) * (lSize+1));
if (ppairs == NULL) {fputs ("Memory error",stderr); free(buffer); return 3;}
Also, remember malloc
expects a size_t
(the definition of which is implementation-dependent) for an argument. 另外,请记住,
malloc
期望参数有一个size_t
(其定义与实现有关)。 Make sure that when you pass (sizeof(bitpair) * (lSize+1))
to malloc
, you are not overflowing a size_t
(if size_t
is defined as unsigned int
, you could run into problems since lSize
is a long
). 确保当你通过
(sizeof(bitpair) * (lSize+1))
来malloc
,你是不是一个满溢size_t
(如果size_t
被定义为unsigned int
,你可能会遇到的问题,因为lSize
是一个long
)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.