2014-09-26 117 views
1
  1. 我有一個結構稱爲MENU_ITEM,看起來像:傳遞指針數組到功能

    struct menu_item 
    { 
        char name[ITEM_NAME_LEN+1]; 
    }; 
    
  2. 而在主本人聲明指針數組的結構(我說的對這個部分?):

    struct menu_item * menu_items[NUM_MENU_ITEMS]; 
    
  3. 而且還在主我試圖撥打:

    init_menu(&menu_items[NUM_MENU_ITEMS]); 
    
  4. init_menu功能如下:

    void menu_init(struct menu_item * menu_items[NUM_MENU_ITEMS]) 
    { 
        /* allocate memory for each element in the array */ 
        menu_items[NUM_MENU_ITEMS] = (struct menu_item *) malloc(sizeof(struct menu_item)); 
    } 
    

但是我得到一個分割錯誤,我究竟做錯了什麼?提前致謝。

+0

請參閱[C亂碼英文](http://cdecl.org)並輸入'struct menu_item * menu_items [3];'以獲得一些指導。 – chux 2014-09-26 15:28:44

+0

'init_menu(&menu_items [NUM_MENU_ITEMS]);'將指針傳遞給數組末尾的不存在的元素。只是缺乏一些基本的語法知識,在這裏。 – 2014-09-26 15:29:09

回答

2

仔細看看你的功能。

void menu_init(struct menu_item * menu_items[NUM_MENU_ITEMS]) 
{ 
    /* allocate memory for each element in the array */ 
    menu_items[NUM_MENU_ITEMS] = (struct menu_item *) malloc(sizeof(struct menu_item)); 
} 

您需要在函數的第二個參數中攜帶數組的大小。但是,NUM_MENU_ITEMS,似乎是全球的#define,因此您不需要攜帶第二個參數。

然後,您正在訪問一個出界的單元格menu_items[NUM_MENU_ITEMS]。我假設你知道索引從0開始到NUM_MENU_ITEMS-1結束。

在你的函數中,你需要在一個循環內部分配內存。而且,你不需要施放malloc返回的東西。

因此,舉例來說,你可以做這樣的事情:

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

#define ITEM_NAME_LEN 15 
#define NUM_MENU_ITEMS 3 

// Define the struct before main 
struct menu_item { 
    char name[ITEM_NAME_LEN + 1]; 
}; 

// Give a synonym. Now struct menu_item is the same with menu_item_t. 
// Notice the _t extension, which implies that this is a typedef. 
typedef struct menu_item menu_item_t; 

/** 
* Given a pointer 'p' to an array of pointers 
* (of type menu_item_t), allocate memory for 
* every cell of the array. 
*/ 
void init_menu(menu_item_t* p[]) { 
    int i; 
    for(i = 0; i < NUM_MENU_ITEMS; ++i) { 
    // for every cell of our array, allocate memory 
    p[i] = malloc(sizeof(menu_item_t)); 

    // check that allocation for the i-th cell is OK 
    if(!p[i]) { 
     printf("Error in allocating %d item!\n\n", i); 
     return; 
    } 
    } 
} 

/** 
* Given a pointer 'p' to an array of pointers 
* (of type menu_item_t), de-allocate memory for 
* every cell of the array. 
*/ 
void delete_menu(menu_item_t* p[]) { 
    int i; 
    for(i = 0; i < NUM_MENU_ITEMS; ++i) { 
    // free the memory we had allocated for the i-th cell 
    free(p[i]); 

    // set the pointer to NULL 
    p[i] = NULL; 
    } 
} 

void fill(menu_item_t* p[]) { 
    int i; 
    for(i = 0; i < NUM_MENU_ITEMS; ++i) { 
    strcpy(p[i]->name, "myitem"); 
    } 
} 

void print(menu_item_t* p[]) { 
    int i; 
    for(i = 0; i < NUM_MENU_ITEMS; ++i) { 
    printf("%s\n", p[i]->name); 
    } 
} 

int main(void) { 
    // Declare an array of pointers of menu_items_t. 
    // The size of the array is NUM_MENU_ITEMS 
    menu_item_t *menu_items[NUM_MENU_ITEMS]; 

    init_menu(menu_items); 

    fill(menu_items); 

    print(menu_items); 

    delete_menu(menu_items); 

    return 0; 
} 

當我處理結構,我一直都對心靈this例子。

+1

+1用於處理分配問題(注意:最好使用'free(p [i]); p [i] = NULL;'delete_menu()'_may_不是'menu_items'的最終用法。 – chux 2014-09-26 15:53:07

1

要調用你的函數作爲

init_menu(&menu_items[NUM_MENU_ITEMS]); 

這是沒有意義的。表達式&menu_items[NUM_MENU_ITEMS]創建索引爲NUM_MENU_ITEMS的元素的指針。這樣的元素不存在。您的陣列的元素編號從0NUM_MENU_ITEMS - 1。沒有索引NUM_MENU_ITEMS的元素。

表達式&menu_items[NUM_MENU_ITEMS]在數組的末尾產生一個指向未知存儲器的指針。您將該指針傳遞給函數。後來你試圖使用該指針,就好像它是你的數組一樣。你寫入那個導致崩潰的未知內存。

如果您想將數組傳遞給函數,只需傳遞它即可。你的功能應該叫做

init_menu(menu_items); 

就是這樣。沒有必要創建任何指向具有奇怪索引的元素的指針。

後,你的函數中你又試圖訪問您的陣列

menu_items[NUM_MENU_ITEMS] = ... 

此元素NUM_MENU_ITEMS無厘頭無論是對非常相同的原因。