2012-09-14 45 views
4

我有一個包含事務數組的BankAccount結構。存款和取款在本數組中存儲爲+/- ints。用fwrite寫結構到文件時valgrind錯誤 - 系統調用參數寫入(buf)指向未初始化的字節

struct BankAccount { 
    char name[NAME_LENGTH]; 
    int num_of_transactions; 
    int transactions[MAX_TRANSACTIONS]; 
}; 

我在堆上爲結構分配空間並在完成時處置它。我使用fwrite將此結構保存到文件中。

struct BankAccount *new_bank_account(char name[], int initial_deposit) { 
    struct BankAccount *acc = malloc(sizeof(struct BankAccount)); 

    strncpy(acc->name, name, NAME_LENGTH); 
    acc->num_of_transactions = 0; 

    int i; 
    for (i = 0; i < MAX_TRANSACTIONS; i++) { 
     acc->transactions[i] = 0; 
    } 

    if (initial_deposit != 0) { 
     make_deposit(acc, initial_deposit); 
    } 

    return acc; 
} 

void delete_bank_account(struct BankAccount *acc) { 
    free(acc); 
} 

int save_bank_account(struct BankAccount *acc, char filepath[]) { 
    FILE *fp = fopen(filepath, "w"); 
    int res = 0; 

    res = fwrite(acc, sizeof(struct BankAccount), 1, fp); 

    fclose(fp); 
    return res; 
} 

的代碼按預期工作,我能夠做出一個賬戶的交易,並將其保存到磁盤並重新加載它。我的測試代碼如下。

void test_bank_account_balance() { 
    struct BankAccount *acc = new_bank_account("John Doe", 0); 
    make_deposit(acc, 50); 
    make_deposit(acc, 100); 
    make_withdrawal(acc, 50); 

    printf("%s has balance = $ %d\n", acc->name, get_balance(acc)); 

    delete_bank_account(acc); 
} 

int main(int argc, char *argv[]) { 
    test_save_bank_account(); 
    return 0; 
} 

然而,當我通過Valgrind的運行它,它給了我關於未初始化的字節錯誤。我懷疑在new_bank_account中缺少一些初始化。但我無法看到那是什麼。

==4311== Syscall param write(buf) points to uninitialised byte(s) 
==4311== at 0x411E1D3: __write_nocancel (syscall-template.S:82) 
==4311== by 0x40B2B04: [email protected]@GLIBC_2.1 (fileops.c:1289) 
==4311== by 0x40B29E3: new_do_write (fileops.c:543) 
==4311== by 0x80489B0: test_save_bank_account (p14.c:124) 
==4311== by 0x8048A1D: main (p14.c:140) 
==4311== Address 0x4035032 is not stack'd, malloc'd or (recently) free'd 
==4311== Uninitialised value was created by a heap allocation 
==4311== at 0x402BD14: malloc (vg_replace_malloc.c:270) 
==4311== by 0x80486B5: new_bank_account (p14.c:41) 
==4311== by 0x8048956: test_save_bank_account (p14.c:118) 
==4311== by 0x8048A1D: main (p14.c:140) 

請幫忙!謝謝。

+2

你應該小心使用'strncpy',因爲如果它複製了所有的'NAME_LENGTH'字符,它就不會在字符串中加入'\ 0'。 –

+0

謝謝,很高興知道。 – mathguy80

回答

5

我猜想struct BankAccountnamenum_of_transactions成員之間有一些填充。

這大概沒有什麼可擔心的,但如果你想沉默valgrind,使用calloc()來分配內存應該工作。或者memset(acc, 0, sizeof(*acc))

+0

我試過calloc和那個作品,謝謝。 – mathguy80

+0

還有另一個答案,這裏也提示memset,不知道爲什麼它不再顯示。但我嘗試過,但仍然給出了同樣的錯誤。我甚至做了一個memset(acc-> name,'a',sizeof(acc-> name));與同樣的錯誤。任何想法爲什麼? – mathguy80

+0

好吧,sizeof(* acc)通過調整所有內容來實現,但sizeof(acc-> name)不會。進一步sizeof(acc-> name)+ sizeof(int)的工作,有趣... – mathguy80

相關問題