Saya mencoba menambahkan banyak WCHAR ke buffer. Fungsi inilah yang menambahkannya ke buffer saya ..

DWORD add_to_buffer(BYTE *databuffer, WCHAR *path, WCHAR *value_name, DWORD type, BYTE *data, DWORD data_size, DWORD already_added) {
    DWORD path_size = wcslen(path) * 2;
    DWORD value_name_size = wcslen(value_name) * 2;

    WCHAR *type_name = reg_type_to_wchar(type);
    DWORD type_size = wcslen(type_name) * 2;


    DWORD total_length = already_added + path_size + value_name_size + type_size + data_size;

    *databuffer = realloc(databuffer, total_length);
    
    CopyMemory(databuffer, path, path_size);
    CopyMemory(databuffer + path_size, value_name, value_name_size);
    CopyMemory(databuffer + path_size + value_name_size, type_name, type_size);
    CopyMemory(databuffer + path_size + value_name_size + type_size, data, data_size);
        
    return total_length;
}

Pada panggilan kedua ke add_to_buffer() realloc() gagal. Saya pada dasarnya memanggil fungsi ini berulang-ulang, sambil menambahkan informasi ke dalamnya dan membuatnya lebih besar sesuai kebutuhan. Saya tidak yakin bagaimana memecahkan masalah ini karena semua yang ada di VS terlihat benar saat masuk ke fungsi. databuffer tidak dibebaskan di mana pun di luar fungsi ini.

3
Stack Overflow 23 Desember 2020, 18:49

3 jawaban

Jawaban Terbaik

Anda mencampuradukkan level tipuan pointer. Misalnya, di baris Anda, *databuffer = realloc(databuffer, total_length); Anda (di sisi kiri) mereferensikan variabel databuffer tetapi, di dalam panggilan, Anda tidak.

Jika Anda ingin fungsi Anda memodifikasi pointer (yang dilakukannya), maka Anda harus meneruskan pointer ke pointer itu, sehingga nilai yang dimodifikasi (alamat baru) tersedia untuk modul pemanggil. Seperti ini:

DWORD add_to_buffer(BYTE **databuffer, WCHAR *path, WCHAR *value_name, DWORD type, BYTE
 *data, DWORD data_size, DWORD already_added) { // Pass a "databuffer" as a DOUBLE pointer
    DWORD path_size = wcslen(path) * 2;
    DWORD value_name_size = wcslen(value_name) * 2;

    WCHAR *type_name = reg_type_to_wchar(type);
    DWORD type_size = wcslen(type_name) * 2;

    DWORD total_length = already_added + path_size + value_name_size + type_size + data_size;

    // It is also bad practice to overwrite the argument in "realloc" calls; save to a
    // temp, so that you can check for failure ...
    BYTE *temp = realloc(*databuffer, total_length); // Not the "*" before databuffer!
    if (temp == NULL) { // Allocation failure ...
        // Here, place code to handle/signal the error
        // But note that we STILL HAVE THE ORIGINAL POINTER!
        return 0; // and return a value that indicates failure
    }
    *databuffer = temp; // Succeeded: we can now safely reassign the passed pointer.
    
    // We now need to also dereference the double pointer in the following calls ...
    CopyMemory(*databuffer, path, path_size);
    CopyMemory(*databuffer + path_size, value_name, value_name_size);
    CopyMemory(*databuffer + path_size + value_name_size, type_name, type_size);
    CopyMemory(*databuffer + path_size + value_name_size + type_size, data, data_size);
        
    return total_length;
}
3
Adrian Mole 23 Desember 2020, 16:01
*databuffer = realloc(databuffer, total_length);

Di sini Anda menetapkan nilai yang dikembalikan oleh realoc ke byte pertama databuffer. Anda seharusnya tidak melakukan dereference databuffer.

1
Skult 23 Desember 2020, 16:00

mengalokasikan kembali nilai pengembalian: "Fungsi ini mengembalikan pointer ke memori yang baru dialokasikan, atau NULL jika permintaan gagal." Pada panggilan ke-2, seharusnya tidak ada lagi ruang yang tersedia untuk dialokasikan kembali ... saya pikir cara termudah adalah mengubahnya sebagai: *databuffer = realloc(databuffer, total_length); if(databuffer == NULL) { *databuffer = malloc(total_length); }

1
Devi Khositashvili 23 Desember 2020, 16:03