我在运行代码时遇到臭名昭着的malloc.c:3074错误(编译没有问题)。我使用-g选项编译。我使用Valgrind来确定内存分配问题发生的位置,但结果并没有帮助很多。这是Valgrind的输出:
==2710== Invalid write of size 8
==2710== at 0x400FC8: generatePairs (ldbalpha.c:42)
==2710== by 0x400BFA: main (ldb-stegoencoderalpha.c:53)
==2710== Address 0x51997c8 is not stack'd, malloc'd or (recently) free'd
==2710==
==2710== Invalid write of size 8
==2710== at 0x401047: generatePairs (ldbalpha.c:54)
==2710== by 0x400BFA: main (ldb-stegoencoderalpha.c:53)
==2710== Address 0x51997a8 is 0 bytes after a block of size 1,160 alloc'd
==2710== at 0x4C25153: malloc (vg_replace_malloc.c:195)
==2710== by 0x400BA6: main (ldb-stegoencoderalpha.c:49)
==2710==
==2710== Invalid write of size 8
==2710== at 0x401054: generatePairs (ldbalpha.c:55)
==2710== by 0x400BFA: main (ldb-stegoencoderalpha.c:53)
==2710== Address 0x51997b0 is 8 bytes after a block of size 1,160 alloc'd
==2710== at 0x4C25153: malloc (vg_replace_malloc.c:195)
==2710== by 0x400BA6: main (ldb-stegoencoderalpha.c:49)
==2710==
==2710== Invalid write of size 8
==2710== at 0x401062: generatePairs (ldbalpha.c:56)
==2710== by 0x400BFA: main (ldb-stegoencoderalpha.c:53)
==2710== Address 0x51997c0 is not stack'd, malloc'd or (recently) free'd
这是main函数后跟被调用函数generatePairs。我将行号列为与valgrind输出对应的注释:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <malloc.h>
#include "ldb.h"
int main(int argc, char * argv[]) {
FILE *pFile;
unsigned char *buffer;
int i, j;
char ch = '\0';
long unsigned int lSize;
if (argc != 3) {
fprintf(stderr, "Usage: ./ldb-stegoencoderalpha [Stegofile] [messages.txt] > [messages-encoded.txt]\n");
return 1;
} // end if
pFile = fopen ( argv[1] , "r" );
if (pFile==NULL) {fputs ("File error on arg[1]",stderr); exit (1);}
// obtain file size:
fseek (pFile , 0 , SEEK_END); // Go to end of File
lSize = ftell (pFile); // Return # of Bytes in the file
rewind (pFile); // Rewind to start of file
// allocate memory to contain the whole file:
buffer = malloc(sizeof(char) * lSize+1);
if (buffer == NULL) {fputs ("Memory error",stderr); exit (2);}
bitpair * ppairs = malloc(sizeof(bitpair) * (lSize+1)); // Line 49,Structure setup
memset (ppairs, 0, sizeof(bitpair) * (lSize+1)); //zeroize it first
generatePairs(ppairs, lSize+1); //Line 53 in Valgrind error
之后我用这些对进行一些计算,但Valgrind错误来自generatePairs和malloc函数。这是generatePairs函数:
#include <string.h>
#include <assert.h>
#include "ldb.h"
void generatePairs(bitpair * ppairs, long unsigned int bits) {
unsigned int i, rand1, rand2, high, low;
unsigned int count = 1;
// initialize the array of pairs
for(i = 1; i <= bits; i++) {
bitpair * bp = &ppairs[i];
bp->ref = -1;
bp->enc = -1;
bp->len = -1;
bp->bit = -1;
bp->used = 0;
}
for(i = 1; i <= bits; i++) {
rand1 = 0;
ppairs[rand1].used = 1;
rand2 = count;
count++;
assert(rand2 <= bits);
ppairs[rand2].used = 1; //Line 42 in Valgrind error
high = rand2;
low = rand1;
// initialize both data structures (bp->used is already set)
bitpair * bp = &ppairs[low];
bp->ref = low;
bp->enc = high;
bp->bit = i;
bp = &ppairs[high];
bp->ref = low; //Line 54 in Valgrind error
bp->enc = high; //Line 55 in Valgrind error
bp->bit = i; //Line 56 in Valgrind error
}
return;
}
typedef struct {
long unsigned int ref;
long unsigned int enc;
long unsigned int len;
long unsigned int bit;
long unsigned int used;
} bitpair;
void generatePairs(bitpair * ppairs, long unsigned int bits);
谢谢!
答案 0 :(得分:1)
在分配之前rand2的价值是多少?您可能会在分配的内存之外进行索引,从而导致错误。
编辑:您是否应该每次通过外部for循环重置计数?看起来计数会继续增长超过你分配的数量,导致rand2也增长?最终,您将在分配的内存之外进行索引。
答案 1 :(得分:1)
我会:
unsigned
而不是int
(或更好size_t
)ppairs
,以检查边界,例如assert(rand2 < bits)
之前的ppairs[rand2]