6 Replies - 277 Views - Last Post: 23 January 2013 - 08:26 PM Rate Topic: -----

#1 fyr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 23-January 13

malloc or not to malloc

Posted 23 January 2013 - 07:08 PM

hello. I'd like to know why didn't I need to write malloc for the function below. list_data(element) returns a void*. is it because we don't allocate memory for void pointers?

int* data;
/* some more code */
while(true)
{
         data = list_data(element);
         fprintf(stdout, "list[%03d] = %03d\n", i, *data);
        
         if(list_is_tail(element))
         break;
         else
         element = list_next(element);
         i++;
}



Is This A Good Question/Topic? 0
  • +

Replies To: malloc or not to malloc

#2 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2895
  • View blog
  • Posts: 10,028
  • Joined: 08-August 08

Re: malloc or not to malloc

Posted 23 January 2013 - 07:13 PM

int *data; allocates memory for the pointer just as int data; allocates memory for an integer.
Was This Post Helpful? 0
  • +
  • -

#3 fyr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 23-January 13

Re: malloc or not to malloc

Posted 23 January 2013 - 07:17 PM

I still don't get it. For example I have this snippet too and here I needed to allocate memory for integers.

int main(void)
{
   List list;
   int* data;
   int i;
   /* initialize the list */
   list_init(&list, free);
   /* insert numbers at the head of the list */
   for(i = 9; i >= 0; i--)
   {
     if((data = malloc(sizeof(int))) == NULL)
       return EXIT_FAILURE;   
     
     *data = i;
     if(list_ins_next(&list, NULL, data) != 0)
       return EXIT_FAILURE;  
   }    
   /* print the list */
   print_list(&list);
   return EXIT_SUCCESS;
}


Was This Post Helpful? 0
  • +
  • -

#4 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1072
  • View blog
  • Posts: 4,532
  • Joined: 09-June 09

Re: malloc or not to malloc

Posted 23 January 2013 - 07:44 PM

Quote

I still don't get it. For example I have this snippet too and here I needed to allocate memory for integers.


It is impossible to answer your question without seeing the implementation of your list functions.
Traditionally, all memory location should be handled by the list functions and the client should not have to worry about this.

Quote

void*. is it because we don't allocate memory for void pointer

A void pointer is just a special pointer that doesn't have a specified target type. You can point the pointer anywhere; however, you cannot deference the pointer because the amount of bytes to deference is not known.
Was This Post Helpful? 0
  • +
  • -

#5 CTphpnwb  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2895
  • View blog
  • Posts: 10,028
  • Joined: 08-August 08

Re: malloc or not to malloc

Posted 23 January 2013 - 07:48 PM

You needed to allocate memory for them because you added them to a linked list that you want to be able to access outside the scope of main() when you call print_list().
Was This Post Helpful? 1
  • +
  • -

#6 fyr  Icon User is offline

  • New D.I.C Head

Reputation: 0
  • View blog
  • Posts: 15
  • Joined: 23-January 13

Re: malloc or not to malloc

Posted 23 January 2013 - 08:06 PM

View Postjjl, on 23 January 2013 - 07:44 PM, said:

It is impossible to answer your question without seeing the implementation of your list functions.


What I coded so far:

/*****************************************************************************
*                                                                            *
*  -------------------------------- list.h --------------------------------  *
*                                                                            *
*****************************************************************************/

#ifndef LIST_H
#define LIST_H

#include <stdlib.h>

/*****************************************************************************
*                                                                            *
*  Define a structure for linked list elements.                              *
*                                                                            *
*****************************************************************************/

typedef struct ListElmt_ {

void               *data;
struct ListElmt_   *next;

} ListElmt;

/*****************************************************************************
*                                                                            *
*  Define a structure for linked lists.                                      *
*                                                                            *
*****************************************************************************/

typedef struct List_ {

int                size;

int                (*match)(const void *key1, const void *key2);
void               (*destroy)(void *data);

ListElmt           *head;
ListElmt           *tail;

} List;

/*****************************************************************************
*                                                                            *
*  --------------------------- Public Interface ---------------------------  *
*                                                                            *
*****************************************************************************/

void list_init(List *list, void (*destroy)(void *data));

void list_destroy(List *list);

int list_ins_next(List *list, ListElmt *element, const void *data);

int list_rem_next(List *list, ListElmt *element, void **data);

#define list_size(list) ((list)->size)

#define list_head(list) ((list)->head)

#define list_tail(list) ((list)->tail)

#define list_is_head(list, element) ((element) == (list)->head ? 1 : 0)

#define list_is_tail(element) ((element)->next == NULL ? 1 : 0)

#define list_data(element) ((element)->data)

#define list_next(element) ((element)->next)

#endif



#include "list.h"

void list_init(List* list, void (*destroy)(void* data)) {

    /* initialize all the list data */
    list->size = 0;
    list->destroy = destroy;
    list->head = NULL;
    list->tail = NULL;
    
}

int list_ins_next(List* list, ListElmt* element, const void* data) {

    /* insert new data inside a new element */
    ListElmt* new_element;
    if((new_element = malloc(sizeof(ListElmt))) == NULL)
       return -1;
    new_element->data = (void*) data;
    
    /* insert the new element at the head of the list */
    if(element == NULL)
    {  
        if(list_size(list) == 0)
          list->tail = new_element;
    
        new_element->next = list->head;  
        list->head = new_element;
    }    
    /* insert new element at another place other than the head */
    else {
      
        if(element->next == NULL)
           list->tail = new_element;
        
        new_element->next = element->next;
        element->next = new_element;
    }
    /* update the list size */
    list->size++;
    return 0;    
}



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

#include "list.h"

static void print_list(List* list)
{
    ListElmt* element;
    int* data;
    int i = 0;
   
   /* display the size of the list */
    fprintf(stdout, "List size is %d\n", list_size(list));
   /* display each data of the elements of the list */ 
   for(element = list_head(list); element != NULL; element = list_next(element))
   {
      data = list_data(element);
      fprintf(stdout, "list[%03d] = %03d\n", i, *data);
      i++;
   }    
}

int main(void)
{
   List list;
   int* data;
   int i;   
   /* initialize the list */
   list_init(&list, free);
   /* insert numbers at the head of the list */
   for(i = 9; i >= 0; i--)
   {
      if((data = malloc(sizeof(int))) == NULL)
        return EXIT_FAILURE;     
      *data = i;
      if(list_ins_next(&list, NULL, data) != 0)
        return EXIT_FAILURE;   
   }    
   /* print the list */
   print_list(&list);
   return EXIT_SUCCESS;
}


Was This Post Helpful? 0
  • +
  • -

#7 jjl  Icon User is offline

  • Engineer
  • member icon

Reputation: 1072
  • View blog
  • Posts: 4,532
  • Joined: 09-June 09

Re: malloc or not to malloc

Posted 23 January 2013 - 08:26 PM

int list_ins_next(List* list, ListElmt* element, const void* data) 


You should remove the dependency to allocate run time memory in your list in your client code. The purpose of these functions is to provide an "ease of use" and not clutter them down with pre conditions. I would add an extra parameter to this function to represent the number of bytes that data is and get rid of all memory allocation from main.

Here is crude example of what I am talking about
#include <stdio.h>
#include <string.h>
#include <stdlib.h>

typedef struct Node {
   void *data;
   int bytes;
   struct Node *next;
} Node;

void listAdd(Node **head, void *data, int bytes) {
   Node *temp = malloc(sizeof(Node));

   //allocate bytes for data
   temp->data = malloc(bytes);
   //copy data to node
   memcpy(temp->data, data, bytes);
   temp->next = *head;
   *head = temp->next;
}


int main() {
   Node *list = NULL;
   int myInt = 1;
   double myDouble = 2.3;
   char myChar = 'a';

   //pass pointer to data with number of bytes that it occupies
   listAdd(&list, &myInt, sizeof(myInt));
   listAdd(&list, &myDouble, sizeof(myDouble));
   listAdd(&list, &myChar, sizeof(myChar));
   return 0;
}


This post has been edited by jjl: 23 January 2013 - 08:37 PM

Was This Post Helpful? 0
  • +
  • -

Page 1 of 1