Ошибка Valgrind m64 m32


Я пытаюсь проверить этот тест файла кода.c ниже с помощью valgrind, когда я делаю тест gcc.c-o тест я получаю следующую ошибку

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)

Но когда я запускаю тест gcc.c-o тест, а затем valgrind я не получаю никакой ошибки. Мой вопрос в том, что происходит с валгриндом в этом случае? Есть ли способ запустить valgrind для 32 или 64 бит?

#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 Но проблема возникает, когда я пытаюсь прочитать файл. Я отредактировал свой код выше. Я получаю ошибку чтения fileError чтение fileError значение

1 5

1 ответ:

Валгринд прав, что беспокоится. В этой строке

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

Вы записываете на 1 байт больше данных, чем разрешено; один за вашей новой временной строкой стека. Вы, вероятно, перепутали запись строки (с +1 для конечного нуля) с записью точно (максимального) размера буфера, используемого:

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

Поскольку вы сбрасываете содержимое памяти в файл, вы должны очистить строковую память перед использованием sprintf. Вы никогда не знаете, что находится внутри только что выделенной памяти!
Примечание что если вы беспокоитесь о целостности данных, всегда лучше использовать безопасный вариант sprintf_s, так как он защитит вас от перегрузки этого буфера.