2015-10-14 52 views
0

我有一個結構如何分配內存的int數組的結構

typedef struct 
{ 
    int size; //size of array 
    int array* 
} 

如何使用尺寸變量和malloc的int數組分配內存?

+0

或者我需要做一些初始化函數,如果是的話,那會是什麼樣子? –

+1

'struct s; S->大小= SOME_SIZE; s - > array = malloc(s-> size *(sizeof * s-> array));' – kaylum

+1

可能的重複[如何正確malloc爲C數組結構](http://stackoverflow.com/questions/ 19613752 /如何正確malloc爲陣列結構在C) – skrrgwasme

回答

1
int *ptr; 
ptr = malloc(sizeof *ptr * size); 
//can now reference ptr[0], ptr[1], ... ptr[size-1]. 

上述代碼的作用:當爲一個int數組分配內存,可以分配4個字節的存儲器(的sizeof(int)的),用於每次需要元素。所以,當你使用malloc時,malloc會將元素的大小乘以你需要的元素數量。

1

您可以創建初始化結構的功能,你可以創建一個這樣的:

typedef struct { 
    int size; //size of array 
    int *array; 
} mystruct; 

mystruct * create_mystruct(int size) { 
    mystruct * st = (mystruct*) malloc(sizeof(mystruct)); 
    st->size = size; 
    st->array = (int *) malloc(sizeof(int) * size); 
    return st; 
} 

Here是工作吡咯烷酮作爲一個例子。

+0

非常感謝這真的清除了東西:) –

+0

不客氣:)。還要記住,你必須釋放()所有你保留的資源malloc() – Hawkings

+0

'st-> array =(int *)malloc(sizeof(int)* size);'鑄造'maloc()'結果不需要。使用'sizeof *指針'更安全 - >'st-> array = malloc(sizeof *(st-> array)* size);'測試'NULL'返回缺失。 – chux

1

您的問題的答案將取決於您是否聲明struct指針指向struct。如果你聲明一個結構體(例如mystruct s),那麼你只需要分配內存元素s.array。例如: -

typedef struct mystruct { 
    int size; 
    int *array; 
} mystruct; 
... 

mystruct s; 

s.size = 5; 

/* allocating array based on size */ 
s.array = malloc (s.size * sizeof *s.array); 
if (!s.array) { 
    fprintf (stderr, "error: virtual memory exhausted.\n"); 
    return 1; 
} 

注:你必須驗證你的配置成功和malloc實際上每次調用malloc時間返回一個有效的地址。 (你可以創建一個函數來減少輸入)。完成後您只需要免費s.array

然而,如果聲明一個指針struct(例如mystruct *msp = NULL;)你現在必須兩個mspmsp->array分配內存。例如:

mystruct *msp = NULL; 

msp = malloc (sizeof *msp); 
if (!msp) { 
    fprintf (stderr, "error: virtual memory exhausted.\n"); 
    return 1; 
} 

msp->size = 5; 

/* allocating array based on size */ 
msp->array = malloc (msp->size * sizeof *msp->array); 
if (!msp->array) { 
    fprintf (stderr, "error: virtual memory exhausted.\n"); 
    return 1; 
} 

必須free你都完成的時候。

以下是示出在兩種情況下爲array分配,使用和存儲器釋放一個簡單的例子:

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

typedef struct mystruct { 
    int size; 
    int *array; 
} mystruct; 

int main (void) { 

    size_t i = 0; 
    size_t nelements = 0; 
    int rd = 0; 

    /* 
    * declaring a struct mystruct 
    */ 
    mystruct s; 

    s.size = 5; 

    /* allocating array based on size */ 
    s.array = malloc (s.size * sizeof *s.array); 
    if (!s.array) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

    /* fill array */ 
    for (rd = 0; rd < s.size; rd++) 
     if (scanf ("%d", &s.array[nelements]) == 1) 
      nelements++; 

    for (i = 0; i < nelements; i++) 
     printf (" s.array[%zu] = %d\n", i, s.array[i]); 

    /* free allocated memory */ 
    free (s.array); 

    putchar ('\n'); 

    /* 
    * declaring a pointer to mystruct 
    */ 
    mystruct *msp = NULL; 

    /* allocate memory for msp (mystruct pointer) */ 
    msp = malloc (sizeof *msp); 
    if (!msp) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

    msp->size = 5; 

    /* allocating array based on size */ 
    msp->array = malloc (msp->size * sizeof *msp->array); 
    if (!msp->array) { 
     fprintf (stderr, "error: virtual memory exhausted.\n"); 
     return 1; 
    } 

    /* fill array */ 
    rd = 0; 
    nelements = 0; 
    for (rd = 0; rd < msp->size; rd++) 
     if (scanf ("%d", &msp->array[nelements]) == 1) 
      nelements++; 

    for (i = 0; i < nelements; i++) 
     printf (" msp->array[%zu] = %d\n", i, msp->array[i]); 

    /* free allocated memory */ 
    free (msp->array); 
    free (msp); 

    return 0; 
} 

實施例使用/輸出

$ printf "2\n4\n6\n8\n10\n12\n14\n16\n18\n20\n" | ./bin/struct_alloc_int 
s.array[0] = 2 
s.array[1] = 4 
s.array[2] = 6 
s.array[3] = 8 
s.array[4] = 10 

msp->array[0] = 12 
msp->array[1] = 14 
msp->array[2] = 16 
msp->array[3] = 18 
msp->array[4] = 20 

存儲器錯誤檢查

在您編寫動態代碼的任何代碼中y分配內存,所以你必須使用內存錯誤檢查程序。對於Linux valgrind是正常的選擇。濫用一塊可能導致真正問題的內存塊有很多微妙的方法,沒有理由不這樣做。每個平臺都有類似的內存檢查器。它們使用簡單。通過它來運行你的程序。

$ printf "2\n4\n6\n8\n10\n12\n14\n16\n18\n20\n" | valgrind ./bin/struct_alloc_int 
==20515== Memcheck, a memory error detector 
==20515== Copyright (C) 2002-2012, and GNU GPL'd, by Julian Seward et al. 
==20515== Using Valgrind-3.8.1 and LibVEX; rerun with -h for copyright info 
==20515== Command: ./bin/struct_alloc_int 
==20515== 
s.array[0] = 2 
<snip> 
msp->array[4] = 20 
==20515== 
==20515== HEAP SUMMARY: 
==20515==  in use at exit: 0 bytes in 0 blocks 
==20515== total heap usage: 3 allocs, 3 frees, 56 bytes allocated 
==20515== 
==20515== All heap blocks were freed -- no leaks are possible 
==20515== 
==20515== For counts of detected and suppressed errors, rerun with: -v 
==20515== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 2 from 2) 
+0

Minor:'if((int)i == msp-> size)'好奇。看看'if(i == msp-> size)'沒有什麼優勢。如果我們遇到了一個簽名的'size',那麼代碼應該會出錯或者不會讀取任何帶有非正值的'size' - 這意味着重新開始循環。 – chux

+0

是的,我同意。這是霍布森的選擇。我不想要一個'for'循環,因爲我想要基於成功的'scanf'進行增量控制。這裏'i'的邊界對演員來說是安全的。例如'I = 0; ...我++; if(int)i == msp-> size)...'但我仍然不喜歡它。根據成功的'scanf',保留增量的唯一的不太好的方法是添加和初始化'int'計數器。例如'I = 0; int rd = 0; ... i ++,rd ++;如果(rd == msp-> size)...',或者只是用'int'計數器完全替換'i'。 (我想把'nelements'保存爲'size_t')你的想法? –

+0

@chux無論如何都建立在'for'循環上,並且實際上更喜歡它...... –