tags:

views:

120

answers:

3

Suppose there exists a function which returns a message say of the following format:

struct message
{
void* data;
}msgG;

Which would be the best way to extract the data (i.e. Get the message accessible to fun1 in the code): 1- using a global variable 2- Using double pointers(pointer to a pointer)

//Note: msgG is the global variable

void fun2(struct message **ptr)
{
  **ptr = msgCreate(); // msgCreate returns a type struct message;
  msgG = msgCreate();

}

void fun1()
{
....
.....

struct message *ptr;
ptr = malloc(sizeof(struct message));

fun2(&ptr);
...
}

Now we have the message stored in msgG and ptr ? Which is the better one? Using global variable or accessing the pointer since one is allocated in the heap and the other in the bss(not sure of this)?? Is there any other way to deal with this kind of situation?

A: 

It can be as simple as this:

struct message
{
  void* data;
} msgG;


void fun2(struct message the_msg)
{
  /* access the_msg.data */
}

void fun1()
{
  struct message *ptr;
  ptr = malloc(sizeof(struct message));
  ptr->data = ... /* initialize it to something */

  fun2(*ptr);
}

But this way, fun2 won't be able to manipulate the_msg, because it's passed a copy of the structure by-value. It will be able to manipulate the stuff pointed to by the data pointer inside the_msg, because that's a pointer.

If you want to manipulate the contents of the_msg itself, such as retarget the data pointer, fun2 should accept a pointer to message (a double pointer is unnecessary for this).

And a global variable is almost always a bad solution. Don't use it.

Eli Bendersky
@eliben: So when do we exactly use double pointers. I used to think it is used in these kind of situations
tomkaith13
@tomkaith13: double pointers are used when *the pointer* has to be modified, not its contents. One case is when you want a function to create a new pointer to something, and you pass your own pointer as an argument to it.
Eli Bendersky
@tomkaith13: for more on double pointers: http://stackoverflow.com/questions/758673/uses-for-multiple-levels-of-pointer-dereferences, and also http://stackoverflow.com/questions/897366/how-do-pointer-to-pointers-work-in-c
Eli Bendersky
@eliben: I'm a bit confused, shouldn't fun2() have parameters that look like `fun2(struct message* the_msg)`. As in it should use the tag name 'message' and not 'msgG' and then it should be a pointer to that type since that's what you passed it with fun2(ptr). -1 until corrected
SiegeX
@SiegeX: you're right, I'm fixing the call to fun2
Eli Bendersky
+1  A: 

It's good practise to avoid globals.

Note: if you are trying to code object-oriented in C, have a look to this documentation ooc.pdf

nico
+2  A: 

Don't use a global variable. What you're trying to do can be done this way:

void fun2(struct message *ptr)
{
    *ptr = msgCreate();
}

void fun1()
{
    struct message *m = malloc(sizeof *m);
    if (m == NULL) {
        /* error handling */
    }
    fun2(m);
}

If struct message is big, consider not having a function returning such a struct. In most of the cases, it is more efficient to return a pointer to some memory than to return a big automatic variable from a function.

Alok