2015-07-22 13 views
19

Chcę napisać tablicę zawierającą liczby całkowite 16bit jak surowego binarnego do pliku i nie próbował z poniższym przykładzie:dane Suwnice pisząc do binarnego pliku

# define __int8_t_defined 
__intN_t (8, __QI__); 
__intN_t (16, __HI__); 
__intN_t (32, __SI__); 
__intN_t (64, __DI__); 

int main(int argc, char *argv[]) 
{ 
    FILE * rawf; 
    rawf = fopen("./rawPcm","wb"); 
    int16_t buff[] = {0,0,0}; 
    fwrite(buff,sizeof(int16_t), sizeof(buff),rawf); 
    fwrite(buff,sizeof(int16_t), sizeof(buff),rawf); 
    fclose(rawf); 
} 

Jednak wyjście zawiera więcej niż tylko zer .

$ hexdump -v rawPcm 
0000000 0000 0000 0000 85fd 0804 0001 0000 0000 
0000010 0000 85fd 0804 0001      
0000018 

pisze on 0000 0000 0000 85fd 0804 0001 dla każdego fwrite(buff,sizeof(int16_t), sizeof(buff),rawf); podczas Spodziewam się dostać tylko 0000 0000 0000.

Co dodatkowe dane reprezentują 85fd 0804 0001 i jak mogę temu zapobiec?

+8

(Prawie) minimalny i kompletny przykład, zaobserwowany wynik, oczekiwany wynik. Pan, proszę pana, zasługuje na medal. :-D – DevSolar

+1

Dobre stare przepełnienie bufora :) – Luaan

Odpowiedz

19

Co robi dodatkowe dane reprezentują 85fd 0804 0001

ewentualnie niektóre losowe dane śmieci.

Jak zapobiec wystąpieniu tego błędu?

fwrite(buff,sizeof(int16_t), sizeof(buff),rawf); powinien być zapisany jako:

fwrite(buff,sizeof(int16_t), sizeof(buff)/sizeof(buff[0]),rawf); 
/*    ^      ^^^^^^^^^^^^^^^  */ 
/*  size of each object  Count of objects    */ 
/*    (2)     (3)       */ 

/* or */ 
fwrite(buff, sizeof buf[0], sizeof buff/sizeof buff[0], rawf); 

sizeof buff/sizeof buff[0] dostaje array length in number of objects (or members) podczas sizeof buff podaje rozmiar tablicy w bajtach.

Więc czytasz po numerze buff i zapisujesz go w pliku i wywołuje undefined behaviour. W twoim przypadku widzisz losowe dane śmieci zapisane do pliku wyjściowego.

W twoim przypadku, sizeof każdego elementu w buff ma 2 bajty, a buff zawiera 3 elementy, co powoduje, że całkowity rozmiar wynosi 6 bajtów. Podczas pisania fwrite(buff,sizeof(int16_t), sizeof(buff),rawf);, 6 obiektów po 2 bajty są zapisywane do pliku, który nie jest czymś, co chcesz zrobić.

Teraz piszesz 6 danych typu (rozmiar) int16_t począwszy od buff[0] tj. buff[0..5] na wyjściu. buff[0..2] są zgodne z oczekiwaniami, a buff[3..5] są śmieciami.

+0

Czy nie byłoby lepiej użyć 'sizeof (buff [0])' również dla argumentu wielkości elementu? –

+0

@ColonelThirtyTwo Tak, to jest lepsze. –

9

Trzeci argument o numerze fwrite to o numerze elementów o rozmiarze określonym przez drugi parametr. Nie jest to całkowity rozmiar w bajtach, który obecnie wykonujesz.

A więc przekraczasz swój bufor.

Powiązane problemy