2010-06-23 8 views
1

Je reçois l'erreur tristement célèbre malloc.c: 3074 lors de l'exécution de mon code (compile sans problème). J'ai compilé en utilisant l'option -g. J'ai utilisé Valgrind pour déterminer où se situe le problème d'allocation de mémoire, mais les résultats ne sont pas très utiles. Voici la sortie de Valgrind:malloc.c: 3074 + Sortie 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 

Voici la fonction principale suivie par la fonction appelée generatePairs. J'ai énuméré les numéros de ligne sous forme de commentaires pour correspondre à la sortie 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 

Après que je fais des calculs avec ces paires, mais les erreurs Valgrind proviennent des generatePairs et fonctions malloc. Voici la fonction 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); 

Merci!

+0

[C'est apparu sur SO lots.] (http://www.google.com/search?hl=en&q=malloc.c:3074+site:stackoverflow.com&btnG=Search&aq= f & aqi = & aql = & oq = & gs_rfai =) – jjnguy

+0

L'OP semble le savoir et demande de l'aide pour trouver où la corruption de tas pourrait se produire dans ce programme particulier. –

+0

Cela est correct Tyler, j'ai du mal à trouver le problème et j'apprécierais toute rétroaction – Shawn

Répondre

1

Quelle est la valeur de rand2 avant l'affectation? Vous indexez probablement au-delà de la mémoire allouée, provoquant ainsi l'erreur.

EDIT: Si vous réinitialisez le nombre chaque fois via votre boucle for externe? Il semble que count continuera de croître au-delà de ce que vous avez alloué, ce qui a permis à rand2 de croître aussi? Finalement, vous allez indexer au-delà de la mémoire allouée.

+0

Je pense que vous pourriez avoir raison à propos de cette boucle imbriquée, je ne pense pas que j'ai besoin du do-while plus. Je peux juste faire l'assignation rand2 et inc count une fois pour chaque boucle for. J'ai recompilé et ré-exécuté le programme et, malheureusement, je reçois toujours le même problème de tas. – Shawn

+0

Vous commencez 'count' à 1, mais vous bouclez' bits' fois. 'bits' est aussi l'espace que vous avez mis de côté. Si 'bits' est 5, et que vous êtes dans la boucle où' i' est 4, alors 'count' sera égal à' 5'. Cela le place au-delà de la plage de votre mémoire allouée, provoquant ainsi votre erreur. –

+0

En outre, pourquoi initialisez-vous en continu le 0e élément du tableau? –

1

Je voudrais:

  • modifier tous vos indices et limites à unsigned au lieu de int (ou mieux encore size_t)
  • assertions de vente sur les indices à ppairs partout pour vérifier les limites, quelque chose comme assert(rand2 < bits) avant tout ppairs[rand2]
+0

Putting assert (rand2 Shawn

+0

C'est agréable d'entendre que vous l'avez trouvé.Les affirmations vous forcent simplement à écrire toutes les hypothèses que vous avez habituellement. Une autre supposition implicite que vous avez toujours à portée de main est que les indices commencent à 0. Utilisez unsigned dans ce cas. Les indices doivent également avoir la bonne largeur pour votre architecture. Utilisez size_t, vraiment. –