I'm trying to verify this code file test.c below using valgrind, when I make gcc test.c -o test I get the follow error
Syscall param write(buf) points to uninitialised byte(s)
==22765== at 0x4F22870: __write_nocancel (syscall-template.S:81)
==22765== by 0x4EB0002: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1261)
==22765== by 0x4EB14DB: _IO_do_write@@GLIBC_2.2.5 (fileops.c:538)
==22765== by 0x4EB0D5F: _IO_file_close_it@@GLIBC_2.2.5 (fileops.c:165)
==22765== by 0x4EA4B0F: fclose@@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)
but when I run gcc test.c -o test and then valgrind I don't get any error. My question is What happen with valgrind in this case? Is there any way for run valgrind for 32 or 64 bits?
#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 But a problem happens when I trying to read the file. I edited my above code. I get Error reading fileError reading fileError reading
Valgrind is right to worry. In this line
fwrite(newid, sizeof(char), id_lenght+1, node_ptr);
you are writing 1 byte more data than allowed; the one beyond your new temporary stack string. You probably confused writing a string (with a +1 for the terminating zero) with writing exactly the (maximum) buffer size used:
fwrite(newid, sizeof(char), id_length, node_ptr);
Since you are dumping memory contents to a file, you are correct to clear the string memory before using sprintf. You never know what's inside freshly allocated memory!
Note that if you are worried about data integrity, it's always better to use the safe variant sprintf_s instead, as it will guard you from over-running this buffer.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With