简体   繁体   中英

Passing An Array of Pointers to Function

  1. I have a struct called menu_item that looks like:

     struct menu_item { char name[ITEM_NAME_LEN+1]; }; 
  2. And in main I declare an array of pointers to the struct (am I right about this part?):

     struct menu_item * menu_items[NUM_MENU_ITEMS]; 
  3. And also in main I'm trying to call:

     init_menu(&menu_items[NUM_MENU_ITEMS]); 
  4. init_menu function looks like this:

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

However I'm getting a segmentation error, what am I doing wrong? Thanks in advance.

Take a closer look to your function.

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

You need to carry the size of the array in a second parameter in your function. However, NUM_MENU_ITEMS , seems to be a global #define , thus you don't need to carry a second parameter.

Then you are accessing an out of bound cell, menu_items[NUM_MENU_ITEMS] . I assume you know that the indexing starts from 0 and ends at NUM_MENU_ITEMS-1 .

In your function, you need, inside a loop, to allocate memory. Moreover, you don't need to cast what malloc returns.

So, for example, you could do something like this:

#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;
}

When I deal with structs, I always have this example on mind.

You are calling your function as

init_menu(&menu_items[NUM_MENU_ITEMS]);

This does not make sense. Expression &menu_items[NUM_MENU_ITEMS] creates a pointer to element with index NUM_MENU_ITEMS . Such element does not exist. Your array has elements numbered from 0 to NUM_MENU_ITEMS - 1 . There's no element with index NUM_MENU_ITEMS .

Expression &menu_items[NUM_MENU_ITEMS] produces a pointer into the uncharted memory past the end of the array. You pass that pointer to the function. Later you are trying to use that pointer as if it were your array. You write into that uncharted memory, which causes a crash.

If you want to pass your array to the function, just pass it. Your function should be called as

init_menu(menu_items);

That's it. There's no need to create any pointers to any elements with strange indices.

Later, inside your function you are again trying to access element NUM_MENU_ITEMS of your array

menu_items[NUM_MENU_ITEMS] = ...

This does not make sense either for the very same reasons.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM