开发者

Using malloc in C to allocate space for a typedef'd type

开发者 https://www.devze.com 2023-01-26 23:59 出处:网络
I\'m not sure exactly what I need to use as an argument to malloc to allocate space in the table_allocate(int) function. I was thinking just count_table* cTable = malloc(sizeof(count_table*)), but tha

I'm not sure exactly what I need to use as an argument to malloc to allocate space in the table_allocate(int) function. I was thinking just count_table* cTable = malloc(sizeof(count_table*)), but that doesn't do anything with the size parameter. Am I supposed to allocate space for the list_node_t also? Below is what I am working with.

In the .h file I'm given this signature:

//create a count table struct and allocate space for it                         
//return it as a pointer                                                        
count_table_t* table_allocate(int);

Here are the structs that I'm supposed to use:

typedef struct list_node list_node_t;

struct list_node开发者_StackOverflow中文版 {
  char *key;
  int value;

  //the next node in the list                                                   
  list_node_t *next;
};

typedef struct count_table count_table_t;

struct count_table {
  int size;
  //an array of list_node pointers                                              
  list_node_t **list_array;
};


count_table* cTable = malloc(sizeof(count_table*))

is wrong. It should be

count_table* cTable = malloc(sizeof(count_table));

Also, you must allocate memory for list_node_t also seperately.

EDIT:

Apart from what Clifford has pointed about allocating memory for the list node, I think the memory allocation should also be taken care for the char *key inside of the list node.


Your suggestion: count_table* cTable = malloc(sizeof(count_table*)) would only allocate space for a pointer to a count_table.

You'd need

count_table* cTable = malloc(sizeof(count_table) ) ;

Each list node would be separately allocated and cTable->size and cTable->list_array and the last list_node_t::next updated accordingly. Maintaining a pointer to the last node added would make adding nodes faster.

I am not sure why count_table::list_array is of type list_node_t** rather than just list_node_t* (and equally called list_array rather than just list). Is it your intention that it is both an array and a list at the same time? That would be somewhat redundant. The member need only be a pointer to the first node, successive nodes are then accessed via list_node::next


Given that the int is a "size" parameter for the created count_table_t, it appears that you are supposed to both allocate the count_table_t itself, as well as initialise its members.

Initialising the list_array member also involves a memory allocation, so it would look like:

count_table_t *table_allocate(int size)
{
    count_table_t *table = malloc(sizeof *table);
    int i;

    table->size = size;
    table->list_array = malloc(size * sizeof table->list_array[0]);
    for (i = 0; i < size; i++)
        table->list_array[i] = NULL;

    return table;
}

However, you also need to check for some error conditions: the multiplication of size by sizeof table->list_array[0] could overflow, and either of the malloc() calls could fail. So the function should actually look like this:

count_table_t *table_allocate(int size)
{
    count_table_t *table;
    int i;

    /* Check for overflow in list allocation size */
    if (size < 0 || size > (size_t)-1 / sizeof table->list_array[0])
        return NULL;

    table = malloc(sizeof *table);

    if (table == NULL)
        return NULL;

    table->size = size;
    table->list_array = malloc(size * sizeof table->list_array[0]);

    if (table->list_array == NULL) {
        free(table);
        return NULL;
    }

    for (i = 0; i < size; i++)
        table->list_array[i] = NULL;

    return table;
}

(Note that (size_t)-1 is a constant equal to the maximum value of a size_t, which is the type of the parameter to malloc()).


In addition to the other posters who point out that you're only allocating enough space for the pointer, not the space the data you want will occupy, I strongly urge you to do things like this:

count_table* cTable = malloc(sizeof(*cTable));

This will help you in case the type of cTable ever changes, you won't have to adjust two parts to that line, just the type.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号