2014-10-27 40 views
0

我是一個初學者,我做了一些練習,學習C.Ç - 的malloc與結構的循環與指針

我的工作與結構和指針的動態內存分配。我有這樣的結構:

struct fact_entry 
{        /* Definition of each table entry */ 
    int n; 
    long long int lli_fact;  /* 64-bit integer */ 
    char *str_fact; 
}; 

這是我的主要代碼:

int 
main (int argc, char *argv[]) 
{ 
    int n; 
    int i; 
    struct fact_entry *fact_table; 

    if (argc != 2) 
    panic ("wrong parameters"); 

    n = atoi (argv[1]); 
    if (n < 0) 
    panic ("n too small"); 
    if (n > LIMIT) 
    panic ("n too big"); 

/* Your code starts here */ 

int p; 

     fact_table = (struct fact_entry *)malloc(n*sizeof(struct fact_entry)); 
     if(fact_table==NULL) 
     { 
    fprintf(stderr, "Out of memory, exiting\n"); 
    exit(1); 
     } 

for (i = 0; i<= n; i++) 
    { 

     fact_table[i].n = i; 

     p = i; 
     fact_table[i].lli_fact=1; 
     while(p>0) 
     { 
    fact_table[i].lli_fact = p * fact_table[i].lli_fact; 
    p--; 
     } 

     p = (int)log10(fact_table[i].lli_fact)+1; 


    fact_table[i].str_fact = malloc(p); 
    if(fact_table->str_fact==NULL) 
     { 
    fprintf(stderr, "Out of memory, exiting\n"); 
    exit(1); 
     } 
     sprintf(fact_table[i].str_fact,"%lld",fact_table[i].lli_fact); 
    } 


/* Your code ends here */ 

    for (i = 0; i <= n; i++) 
    { 

     printf ("%d %lld %s\n", fact_table[i].n, fact_table[i].lli_fact, 
      fact_table[i].str_fact); 
    } 

    return 0; 
} 

的想法是,以填補20行的陣列。然後每行有3列。在第一列中,它顯示了行「i」的數字,第二行顯示了行數的階乘,第三行與第二行相同,但是是字符串格式。

我使用log10來知道字符串有多長。

程序的執行顯示了這個:

0 1 |g�!�2� 
1 1 1 
2 2 2 
3 6 6 
4 24 24 
5 120 120 
6 720 720 
7 5040 5040 
8 40320 40320 
9 362880 362880 
10 3628800 3628800 
11 39916800 39916800 
12 479001600 479001600 
13 6227020800 6227020800 
14 87178291200 87178291200 
15 1307674368000 1307674368000 
16 20922789888000 20922789888000 
17 355687428096000 355687428096000 
18 6402373705728000 6402373705728000 
19 121645100408832000 121645100408832000 
20 2432902008176640000 2432902008176640000 

線0應該在第三列顯示1,會發生什麼?它出現了malloc錯誤。

謝謝!

+0

未定義的行爲!=「即時保證崩潰」。 (如果只有它!) – 2014-10-27 21:10:41

+0

次要的東西:'sizeof(char)'是1,總是。這是因爲'sizeof(char)'是用於測量C中大小的*單位*;它不可能是其他任何東西(即使你使用的是非常奇怪的硬件,例如15位字節)。所以當分配'char'緩衝區時,你永遠不需要'sizeof'。 – Leushenko 2014-10-27 21:14:36

+0

感謝Leushenko,然後我明白,而不是sizeof(字符)我可以直接把變量p,包含數字的字符數。 – 2014-10-27 21:22:35

回答

0
fact_table = malloc(sizeof(struct fact_entry)); 

爲什麼?在第一種情況下,我只保留一行記憶,是真的嗎? 爲什麼不導致分段錯誤錯誤?

正確。但糟糕的代碼並不意味着崩潰。你會在內存上寫下你不希望分配的內容。但這是你的記憶!取決於實施malloc可能會分配頁面大小的內存塊。這可能意味着4096字節。只有當你覆蓋這個可能會崩潰。或者,如果您從該頁面發出另一個分配,您可能會看到問題。

第二,爲什麼我可以填寫第三欄?我無法分配 內存。我不知道我怎麼可以引用每一行,因爲我有一個 結構與一個循環中的指針...我不知道如何定義malloc中的 迭代。

不確定關注。您可以讓單個malloc一次性分配所有內存。然後手動循環修復str_fact的地址到內存塊中。但這不必要的複雜,雖然確實意味着你只有一個分配。通過@SuperAgenten Johannes提供的答案是IMO的正確方法。

+0

謝謝,你回答了我的第一個問題。第二,在結構定義中我有char * str_fact。在每一行我都需要填寫一個值,但我不知道如何。 – 2014-10-27 21:45:04

+0

沒有抱歉,我仍然不明白。你用str_fact填充fact_table [i] .str_fact =(char *)malloc(6 * sizeof(char));和sprintf(fact_table [i] .str_fact,「test」);我不確定你想要改進什麼。抱歉。 :( – Nostromoo 2014-10-27 21:49:53

+0

這是正確的方式來分配內存? – 2014-10-27 21:54:28

1

不知道我理解你的問題。

fact_table = malloc(sizeof(struct fact_entry)); 

會只爲一個結構分配內存,有一個指向一個二維數組,你會做

fact_entry **fact_table; 
fact_table = malloc(sizeof(struct fact_entry) * RowAmount); 
for(int row=0; row < RowAmount; row++) 
    fact_table[row] = malloc(sizeof(struct fact_entry) * ColAmount); 

對於二維數組現在您已經分配的內存;每一行都有列。現在訪問二維數組,你可能只是做

fact_table[rowIndex][colIndex].myvar 

當使用malloc,realloc的,釋放calloc等,你一定要跟蹤數組大小的自己所以保持變量的行/列數。如果您想要忽略列並只有一排行,請執行以下操作。

fact_entry *fact_table; 
fact_table = malloc(sizeof(struct fact_entry) * RowAmount); 

現在,您可以通過

fact_table[rowIndex].myVar 

訪問結構和不要忘記釋放你的對象

for(int Row=0; Row < RowAmount; Row++) 
    free(fact_table[Row]); 
free(fact_table); 
+0

你忘了釋放行... – 2014-10-27 21:28:51

+0

Yupp,現在編輯的遺憾。 – 2014-10-27 21:33:22

+1

基本上我需要知道如何分配內存並填充str_fact。 – 2014-10-27 21:34:12