2017-05-04 78 views
-3

我想創建一個封裝動態分配數組的結構。它看起來像這樣:Calloc()不分配零

typedef struct IntArray { 
    int *field; 
    size_t length; 
} IntArray; 

然後,我有創造這樣的IntArray結構的函數:

IntArray *createIntArray(size_t length) { 
    IntArray *output; 

    if ((output = malloc(sizeof(IntArray))) == NULL) { 
     return NULL; 
    } 

    output->field = calloc(length, sizeof(int)); 
    output->length = length; 

    return output; 
} 

這裏的主:

int main() { 
    size_t size = 10; 
    IntArray *test = createIntArray(size); 

    for (int i = 0; i < size; i++) { 
     printf("%d\n", test[i]); 
    } 
} 

我希望釋放calloc( )用零初始化內存,但是輸出很奇怪:

screenshot


我認爲這些數字是內存地址,但他們在哪裏來的?每次啓動程序時,數字都會改變,但會保持在1.和6.位置。

爲什麼會發生這種情況?

編輯:

我意外地混合起來釋放calloc()和malloc這裏#1,這個問題實際上與上述

+0

1)'輸出=釋放calloc(長度,的sizeof(int)的)' - >'輸出=釋放calloc(長度,的sizeof(IntArray )''printf(「%d \ n」,test-> field [i]);''''printf(「%d \ n」,test [i]); %d \ n「,test [index] .field [i]);'(未初始化) – BLUEPIXY

+0

如果您使用我們在這裏推薦的模式,那麼這個錯誤不會發生......'output = calloc(length,sizeof * output )' –

+3

3)'test [i]'的類型是'IntArray',而不是'int'。 – BLUEPIXY

回答

3

你要打印一個struct作爲int。如果您打開/關閉編譯器警告(如果使用gcc,則使用-Wall),一個好的編譯器會警告您與之對應。

CreateIntArray創建一個IntArrayfield大小爲length。 如果要打印的分配int陣列可以使用以下:

int main() { 
    size_t size = 10; 
    IntArray *test = createIntArray(size); 

    for (int i = 0; i < size; i++) { 
     printf("%d\n", test->field[i]); 
    } 
} 
0

該變量是IntArray類型的代碼中發生,但你分配的int`的陣列。因此你會得到未定義的行爲錯誤。

擁有一個名爲createIntArray的函數會動態地創建一個int數組的數組,而不是像我期望的那樣只有一個數組,這也很奇怪。這也是一個奇怪的依賴關係,因爲它強制調用者總是使用一個數組數組。

您可能完全想要其他東西。也許是這樣的:

#include <stdlib.h> 
#include <assert.h> 

typedef struct IntArray { 
    size_t length; 
    int field[]; 
} IntArray; 

IntArray* createIntArray(size_t length) 
{ 
    IntArray* result; 
    result = calloc(1, sizeof(IntArray) + sizeof(int[length])); 
    assert(result != NULL); 

    result->length = length; 
    return result; 
} 

int main (void) 
{ 
    IntArray* array[3]; 
    for(size_t i=0; i<3; i++) 
    { 
    array[i] = createIntArray(10); 
    } 
}