将指针数组传递给函数

时间:2014-09-26 15:23:24

标签: c

  1. 我有一个名为menu_item的结构,如下所示:

    struct menu_item
    {
        char name[ITEM_NAME_LEN+1];
    };
    
  2. 在main中我声明了一个指向结构的指针数组(我对这部分是正确的吗?):

    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));
    }
    
  5. 但是我遇到了分段错误,我做错了什么?提前谢谢。

2 个答案:

答案 0 :(得分: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)

您正在将您的功能称为

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);

就是这样。没有必要为任何带有奇怪索引的元素创建任何指针。

稍后,在您的函数内部,您将再次尝试访问数组的元素NUM_MENU_ITEMS

menu_items[NUM_MENU_ITEMS] = ...

由于同样的原因,这没有任何意义。