malloc.c: 3074 + выход Valgrind - PullRequest
       14

malloc.c: 3074 + выход Valgrind

1 голос
/ 23 июня 2010

Я получаю печально известную ошибку 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

Вот основная функция, за которой следует вызываемая функция 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 ]

1 голос
/ 24 июня 2010

Я бы:

  • измените все свои индексы и границы на unsigned вместо int (или даже лучше size_t)
  • помещает утверждения для индексов на ppairs везде, чтобы проверить границы, что-то вроде assert(rand2 < bits) перед любым ppairs[rand2]
1 голос
/ 23 июня 2010

Каково значение rand2 перед назначением?Вы, вероятно, индексируете за пределами выделенной памяти, что вызывает ошибку.

РЕДАКТИРОВАТЬ: Должны ли вы сбрасывать счетчик каждый раз через внешний цикл for?Похоже, количество будет продолжать расти сверх того, что вы выделили, что также приведет к росту rand2?В конце концов, вы будете индексировать за пределами выделенной памяти.

...