2016-12-15 84 views
0
typedef struct { 
    char *word; 
} STR; 

int main() 
{ 
    STR *arr=(STR*)malloc(5*sizeof(*arr)); 
    STR[2].word=(char*)malloc(200*sizeof(char)); 
    STR[2].word=(char*)realloc(,400*sizeof(char)); 
    return 0; 
} 

這不起作用,寫了很多錯誤。 如何動態地在動態數組結構中分配數組?malloc動態數組中的動態數組結構

+0

'STR [2]'應該是'ARR [2 ]',但只有在您確認第一個'malloc'調用成功後。另外,在'malloc'調用上丟失 - 它們是不必要的,根據C89標準可以掩蓋一個錯誤。 –

+0

你錯過了'realloc'的第一個參數。 –

回答

0

這似乎是多餘的。但是,如果您嘗試使用您的結構創建一個字符串數組,其中第三個元素以malloc作爲199個字符的字符串,然後作爲399個字符的字符串實現,您可以這樣做:

STR *arr = (STR*)malloc(5*sizeof(STR)); 
arr[2].word = (char*)malloc(200*sizeof(char)); 
arr[2].word = (char*)realloc(arr[2].word,400*sizeof(char)); 
+1

這可以糾正錯誤,但不是很好的C代碼。 a)不輸出'malloc'的結果,b)使用指針變量的引用,而不是它的類型,例如'STR * arr = malloc(5 * sizeof * arr);',c)'sizeof char)'被定義爲'1',因此告訴編譯器解決代碼混亂的問題; d)理想情況下'realloc'的返回值應該存儲在臨時變量中,所以如果調用失敗,你仍然可以做一些事情與原始數據。 –

-1
#include <stdio.h> 
#include <stdlib.h> 


typedef struct{ 
    char *word; 
}STR; 

int main(){ 
    STR *arr=(STR*)malloc(5*sizeof(STR)); 
    arr[2].word=(char*)malloc(200*sizeof(char)); 
    if(realloc(arr[2].word, 400*sizeof(char))==NULL){ 
     /* increasing char array size from 200 to 400 failed. 200 char array was unchanged */ 
     printf("increasing array size not OK\n"); 
    } 
    else{ 
     printf("increasing array size OK\n"); 
    } 
    free(arr[2].word); 
    free(arr); 
    return 0; 
} 
+1

'printf(「增加數組大小OK \ n」);'不,它不好。 –

+3

...因爲你失去了新的指針。 –

1

您的主要問題是你正在使用的typedefSTR你應該分配和再分配arr[2].word時,可以使用變量名arr

不是投下malloc的回報,這是沒有必要的。詳情請參閱:Do I cast the result of malloc?。所有你需要分配的5 STR數組是:

STR *arr = malloc (5 * sizeof (*arr)); /* allocate array of 5 STR */ 

(注:括號是可選的sizeof,所以它也可以正確地寫入):

STR *arr = malloc (5 * sizeof *arr); /* allocate array of 5 STR */ 

後聲明STR *arr = malloc (5 * sizeof (*arr)),你分配word如下:

arr[2].word = malloc (200 * sizeof *(arr[2].word)); 

STR[2].word = malloc (200 * sizeof *(arr[2].word)); 

您必須驗證每一個分配。例如: -

STR *arr = malloc (5 * sizeof (*arr)); /* allocate array of 5 STR */ 

if (!arr) { 
    fprintf (stderr, "error: virtual memory exhausted.\n"); 
    return 1; /* or handle error as appropriate */ 
} 

決不realloc使用指針本身,如果realloc失敗,你已經失去了指針的原始數據並不能釋放內存。而是使用一個簡單的臨時變量:

void *tmp = realloc (arr[2].word, 400 * sizeof *(arr[2].word)); 
if (!tmp) { 
    fprintf (stderr, "error: realloc() virtual memory exhausted.\n"); 
    return 1; 
} 
arr[2].word = tmp; 

在動態分配內存的任何代碼你寫的,你有2名責任關於分配的任何內存塊:(1)始終保持一個指針起始地址對於內存塊來說,(2)當它不再需要時,它可以是釋放。養成跟蹤和釋放你分配的所有內存的習慣,而不是依靠退出來完成它。當您開始編寫更復雜的代碼來分配代碼中的函數內存時,這將帶來收益。在這種情況下,你將需要:

free (arr[2].word); /* free allocated memory */ 
free (arr); 

把這些作品放在一起,你可以這樣做:

typedef struct { 
    char *word; 
} STR; 

int main (void) 
{ 
    STR *arr = malloc (5 * sizeof (*arr)); /* allocate array of 5 STR */ 

    if (!arr) { /* validate allocation */ 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; /* or handle error as appropriate */ 
    } 

    /* allocate/validate arr[2].word */ 
    if (!(arr[2].word = malloc (200 * sizeof *(arr[2].word)))) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; /* or handle error as appropriate */ 
    } 

    /* realloc/validate using temporary variable */ 
    void *tmp = realloc (arr[2].word, 400 * sizeof *(arr[2].word)); 
    if (!tmp) { 
     fprintf (stderr, "error: realloc() virtual memory exhausted.\n"); 
     return 1; 
    } 
    arr[2].word = tmp; 

    free (arr[2].word); /* free allocated memory */ 
    free (arr); 

    return 0; 
} 

示例使用/ Valgrind的輸出

這是你必須使用一個內存錯誤檢查程序,以確保您沒有超出/超出您分配的內存塊,嘗試讀取或基於未初始化的值進行跳轉,最後確認您已釋放所有已分配的內存。

對於Linux valgrind是正常的選擇。有許多微妙的方法來濫用指針或新的內存塊。使用內存錯誤檢查器可以識別任何問題並驗證您分配的內存的正確使用情況,而不是通過segfault發現問題。每個平臺都有類似的內存檢查器。它們都很簡單,只需通過它運行你的程序。

例如,編譯代碼並保存可執行文件./bin/alloc,那麼您需要做的基本使用valgrind簡單地用你的程序作爲第一個參數運行valgrind

$ valgrind ./bin/alloc 
==8949== Memcheck, a memory error detector 
==8949== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al. 
==8949== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info 
==8949== Command: ./bin/alloc 
==8949== 
==8949== 
==8949== HEAP SUMMARY: 
==8949==  in use at exit: 0 bytes in 0 blocks 
==8949== total heap usage: 3 allocs, 3 frees, 640 bytes allocated 
==8949== 
==8949== All heap blocks were freed -- no leaks are possible 
==8949== 
==8949== For counts of detected and suppressed errors, rerun with: -v 
==8949== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

務必確認所有堆塊被釋放 - 沒有泄漏是可能的和同樣重要的錯誤摘要:0錯誤從0上下文。 (注意:某些操作系統不提供足夠的內存排除文件(排除系統和操作系統內存被報告爲正在使用),這將導致valgrind報告某些內存尚未釋放,儘管您已完成你的工作,並釋放所有塊,你分配,並在你的控制下。)

看看它,讓我知道你是否有任何問題。

(注:C有利於小寫的名稱,保留全部大寫的常量和宏這只是風格,所以它是由你)