2016-04-08 28 views
0

在下面的代碼片段中,我得到一個gcc編譯器警告:「從不兼容的指針類型initArr(& stack,2)傳遞initArr的參數1;」 和一個註釋:「預期的'結構Arr *'但參數的類型是'struct Arr **''」 這對我來說非常有意義。如許多SO帖子所暗示的那樣,將呼叫的和號從initArr(&stack, 2)中刪除,但是會導致另一個警告:「'堆棧'在此函數中被單位化使用:init(stack,2);」並在運行時立即發生段錯誤。編譯器警告和筆記,但下降並不起作用

我在做什麼不正確?

我也試過在malloc sizeof調用中使用struct arr,並且如預期的那樣,沒有改變。

#include<stdio.h> 
#include <stdlib.h> 
#define TYPE int 

struct Arr { 
    TYPE * data; // Pointer to the data array. 
    int size;  // Number of elements in the array. 
    int capacity; // Capacity of the array. 
}; 

void initArr(struct Arr * da, int capacity) { 
    da->data = malloc(sizeof(TYPE) * capacity); 
    da->size = 0; 
    da->capacity = capacity; 
} 

int main() { 
    struct Arr *stack; 
    initArr(&stack, 2); 

    return 0; 
} 
+0

@chux謝謝你,我會盡力把你的格式化。 – Chris

回答

4

由於haccks回答說,

  • 你需要初始化你的指針,所以它指向的實際位置
  • 傳遞指針(而不是地址指針變量)

    int main() 
    { 
        struct Arr realArray; // allocate memory for the Arr (on the CPU's stack) 
        struct Arr *stack;  // pointer variable (undefined) 
    
        stack = &realArray;  // make variable "stack" point to realArray 
    
        initArr(stack, 2);  // pass the pointer to realArray 
    } 
    
+0

這三個答案都是正確的。謝謝紳士! – Chris

3

stack是一個指針,它必須指向一些有效的內存位置。由於stack傳遞給該函數並且未初始化,因此會收到警告。在函數中,你試圖訪問一些隨機的內存位置,這會導致程序崩潰或者程序的任何錯誤行爲,也就是未定義的行爲。

3

更改此:

struct Arr *stack; 

要這樣:

struct Arr stack; 
0

首先看一下你的initArr函數的聲明:

void initArr(struct Arr * da, int capacity) 

你的第一個參數的類型爲「指針結構」

現在看您調用此功能:

struct Arr *stack; 
initArr(&stack, 2); 

我們看到棧的類型是'指向結構體的指針',並且在函數中傳遞堆棧的地址(.i.e。該類型是指向結構體指針的指針)。這是gcc的錯誤是關於什麼的,說明實際上提供了有關該函數所需的類型和要提供

類型有兩種方法來解決這個

  1. 離開聲明的更多信息initArr原樣,然後將函數 從initArr(&stack, 2)更改爲initArr(stack, 2)。在這種情況下,您需要確保在將結構傳遞給函數之前爲結構分配了內存;

    int main() 
    { 
        struct Arr* da = NULL; 
        da = malloc(sizeof(struct Arr)); 
    
        initArr(da, 2); 
    } 
    

或等價地,

 int main 
    { 
     struct Arr  stack; 

     initArr(&stack, 2); 
    } 

我可能會去上面的解決方案之一。

  1. initArr的聲明修改爲initArray(struct Arr** da, int capacity)。您仍然需要確保內存像以前一樣分配。但是,如果你改變initArr到:

    void initArr(struct Arr** da, int capacity) 
    { 
        *da = malloc(sizeof(struct Arr)); 
        (*da)->data = malloc(sizeof(TYPE) * capacity); 
        (*da)->size = 0; 
        (*da)->capacity = capacity; 
    } 
    

在這種情況下,我改變你的initArr功能的語義,這樣,我就初始化結構在同一個地方。主函數中的代碼將保持不變。

N.B.爲了清楚起見,在上面的代碼片段中省略了錯誤檢查,請不要在真實代碼中執行此操作。始終檢查malloc的返回值以確保內存已分配。