Skip to main content
gamedev.net
🔒 Locked

[c] pointer as function argument

Started by bnew Mar 16, 2007 at 4:52 PM 6 replies 700+ views
Original Post
bnew
bnew
I'm rather stuck at the following and a quick search reveals no solution: I have a pointer to a (typedef) structure. I want to initialize this (foo) and use it in another function (e.g. main). So basically, passing through. However, when a function call returns, the value remains unchanged? Why? I mean, in my understanding, I declare a pointer to a value_t structure and initialize with NULL. Then I invoke bar with the value_t structure passed by reference. Next, foo is invoked with again the value_t structure passed by ref. Foo initializes the structure by allocating memory and setting some values. On return in bar, I want to change some value of value_t, but an assertion is fired. Debugging shows that the value_t is still NULL. Why?

#include <stdio.h>
#include <malloc.h>
#include <assert.h>

typedef struct _val
{
	int a;
	int b;
} value_t;

int foo(value_t *val)
{
	val = (value_t*)malloc(sizeof(value_t));
	val->a = 0x65;
	val->b = 0x66;
	assert(val != NULL);
	return 0;
}

int bar(value_t *val)
{
	if (val == NULL)
		foo(val);
	assert(val != NULL);
	val->b++;
	return 0;
}

int main()
{
	value_t *val = NULL;
	bar(val);
	assert(val != NULL);
	free(val);
	return 0;
}
Palidine
Palidine
think of it as passing an int to a function. if you change the value of the int internal to the function, does the value change outside? no. why? because it's pass by value. To change the int you'd pass a reference to the int or a pointer to the int and _then_ you could change it externally. it's no different for a pointer. if you want the value of the pointer to change external to the funciton you need to either pass a reference or a pointer to the pointer.

int foo = 0;int *poo = NULL;void changeFoo( int &fooVar ){    fooVar = 2;}void changePoo( int &*poo ){    poo = new int;    *poo = 2;}void main(){    changeFoo(foo);    changePoo(poo);    //foo and poo are now changed    delete poo;}


-me
ToohrVyk
ToohrVyk
The C version of what Palidine said:
int foo(value_t **val){	*val = (value_t*)malloc(sizeof(value_t));	(*val)->a = 0x65;	(*val)->b = 0x66;	assert(val != NULL);	return 0;}int bar(value_t **val){	if (*val == NULL)		foo(val);	assert(*val != NULL);	(*val)->b++;	return 0;}
bnew
bnew
Thank you all. It makes sense really.
Zahlman
Zahlman
I think you better assert the result of your malloc call *before* trying to use the allocation :) Also, a function that always returns the same thing should usually not return anything at all. Oh, and when you have this extra level of indirection, it's usually easier to work with a temporary and then assign it at the end. Oh, and you're supposed to be #including and not casting your malloc() results, in "modern C" (heh).

void foo(value_t **out) {	value_t* val = malloc(sizeof(value_t));	assert(val); // I find this way more readable.	val->a = 0x65;	val->b = 0x66;	*out = val;}

Topic Locked

This topic has been locked by a moderator. New replies are not allowed.

Sign in to reply to this topic.