2015-05-28 20 views
5

Ich versuche, diese Code Datei test.c unter Verwendung valgrind, um zu überprüfen, wenn ich gcc test.c -o Test machen erhalte ich die folgenden FehlerValgrind Fehler m64 m32

Syscall param write(buf) points to uninitialised byte(s) 
==22765== at 0x4F22870: __write_nocancel (syscall-template.S:81) 
==22765== by 0x4EB0002: [email protected]@GLIBC_2.2.5 (fileops.c:1261) 
==22765== by 0x4EB14DB: [email protected]@GLIBC_2.2.5 (fileops.c:538) 
==22765== by 0x4EB0D5F: [email protected]@GLIBC_2.2.5 (fileops.c:165) 
==22765== by 0x4EA4B0F: [email protected]@GLIBC_2.2.5 (iofclose.c:59) 
==22765== by 0x400986: main (in /home/grados-sanchez/git/merkle-codigos-C/test) 
==22765== Address 0x4025770 is not stack'd, malloc'd or (recently) free'd 
==22765== Uninitialised value was created by a stack allocation 
==22765== at 0x4007E2: node_write (in /home/grados-sanchez/git/merkle-codigos-C/test) 

aber wenn ich gcc laufen test.c -o test und dann valgrind bekomme ich keinen Fehler. Meine Frage ist, was passiert mit Valgrind in diesem Fall? Gibt es eine Möglichkeit, Valgrind für 32 oder 64 Bits auszuführen?

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define id_lenght 6000 
typedef unsigned char * ustring; 
typedef struct { 
    ustring ustr; 
    int height; 
    char id[id_lenght]; 
} node; 

int validation_read(void * ptr_var, size_t sizeof_datatype, int num, 
    FILE * ptr_file) { 
    if (fread(ptr_var, sizeof_datatype, num, ptr_file) <= 0) { 
     printf("Error reading file"); 
     return 1; 
    } 
return 0; 
} 

void node_read(FILE * node_ptr, node * n, int r) { 
    int i; 
    validation_read(n->id, sizeof(unsigned char), id_lenght, node_ptr); 
    validation_read(&(n->height), sizeof(int), 1, node_ptr); 
    validation_read(n->ustr, sizeof(unsigned char) * (r + 1), 1,node_ptr); 
} 

void node_init(node * n, int r) { 
    memset(n, 0, sizeof(node)); 
    n->ustr = malloc((r + 1) * sizeof(unsigned char)); 
    memset(n->ustr, 0, (r + 1)); 
    n->ustr[r] = 0; 
    n->height = -1; 
    memset(n->id,0,id_lenght+1); 
} 


void node_write(FILE * node_ptr, node * n, int r) { 
    int i; 
    char newid[id_lenght]; 
    memset(newid,0,id_lenght); 
    sprintf(newid,"%s",n->id); 
    fwrite(newid, sizeof(char), id_lenght+1, node_ptr); 
    fwrite(&(n->height), sizeof(int), 1, node_ptr); 
    fwrite(n->ustr, sizeof(unsigned char) * (r + 1), 1,node_ptr); 
} 


void node_destroy(node * n) { 
    free(n->ustr); 
    n->height = -1; 
} 

int main(){ 
    FILE * ptr = fopen("juantest","w+"); 
    int r = 64/8; 
    node in; 
    node_init(&in, r); 
    node_write(ptr, &in, r); 
    node_destroy(&in); 
    fclose(ptr); 
} 

EDIT Aber ein Problem tritt auf, wenn ich die Datei zu lesen versuchen. Ich habe meinen obigen Code bearbeitet. Ich erhalte Fehler beim Lesen von fileError beim Lesen von fileError beim Lesen

+0

Ihr Code ist nicht lesbar, bitte formatieren Sie ihn! Und 'sizeof (char) == 1 'per definitionem. –

+1

Ihre "Fehler beim Lesen der Datei" erscheint dreimal, muss bedeuten, dass nichts * in der Datei * geschrieben * ist oder Sie in die Datei schreiben und sofort versuchen, daraus zu lesen. – usr2564301

+0

in Funktion: node_read() und in Funktion: node_write(): jede dieser Funktionen hat eine Variable auf dem Stapel: 'i', die nicht verwendet wird. Schlagen Sie 1) entfernen Sie diese beiden Variablen. 2) Aktivieren Sie alle Warnungen beim Kompilieren und Beheben dieser Warnungen (schließlich kennt der Compiler die Sprache C viel besser als Sie oder ich). – user3629249

Antwort

6

Valgrind ist richtig, um sich Sorgen zu machen. In dieser Zeile

fwrite(newid, sizeof(char), id_lenght+1, node_ptr); 

Sie schreiben 1 Byte mehr Daten als erlaubt; Die eine über Ihre neue temporäre Stack-Zeichenfolge. Sie verwirrt wahrscheinlich eine Zeichenfolge (mit einem +1 für die abschließende Null) das Schreiben mit dem Schreiben genau die (maximal) Puffergröße verwendet:

fwrite(newid, sizeof(char), id_length, node_ptr); 

Da Sie Speicherinhalte in eine Datei Dumping, Sie sind richtig die Zeichenfolge löschen Speicher vor der Verwendung sprintf. Sie wissen nie, was in frisch zugeteiltem Speicher ist!
Beachten Sie, dass es immer besser ist, die sichere Variante sprintf_s zu verwenden, wenn Sie sich Sorgen um die Datenintegrität machen, da dies Sie daran hindert, diesen Puffer zu überschreiben.

+1

führen, aber ich möchte ein festes Längen Array schreiben newid – Juan

+0

@Juan: Messepunkt (und ich war frage mich, wie du die Saite zurücklesen würdest!). Inverted meine Antwort, und ein +1 für Sie zum Löschen der Zeichenfolge vor dem Schreiben auf die Festplatte. Aber schauen Sie sich die '_s' Funktionen zur Sicherheit an. Verwenden Sie auch ALL_CAPS für '# define's - es ist eine Konvention, aber eine ziemlich starke. – usr2564301

+0

Ich bearbeite meine Frage ... – Juan