malloc.c:3074 + Valgrind输出

时间:2010-06-23 19:27:36

标签: c malloc valgrind

我在运行代码时遇到臭名昭着的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);

谢谢!

2 个答案:

答案 0 :(得分:1)

在分配之前rand2的价值是多少?您可能会在分配的内存之外进行索引,从而导致错误。

编辑:您是否应该每次通过外部for循环重置计数?看起来计数会继续增长超过你分配的数量,导致rand2也增长?最终,您将在分配的内存之外进行索引。

答案 1 :(得分:1)

我会:

  • 将所有索引和界限更改为unsigned而不是int(或更好size_t
  • 将索引上的断言添加到ppairs,以检查边界,例如assert(rand2 < bits)之前的ppairs[rand2]