Thread: Passing a pointer that might not be needed into a function?

  1. #1
    Registered User
    Join Date
    Dec 2007
    Posts
    15

    Passing a pointer that might not be needed into a function?

    Is there an elegant way to pass a pointer to a function that might not even be needed?

    For example, one way I've been able to do something is:
    Code:
    void function()
    {
        int* thing = malloc(<some size>);
        int size = 0;
    
        while(# of iterations)
        {
            someFunction(thing, &size);
    
            someOtherFunction(thing);
        }
    
    }
    
    void someFunction(int* thing, int*size)
    {
        if(somethingHappens)
        {
                if(*size > 0)
                     thing = (int*)realloc(sizeof(int) * (*size + 1));
        
                 thing[size] = someData;
                 size++;
        }
         
        //other stuff goes here
    
    }
    But doing it the way above, if someFunction isn't used that much the program could run fine, but if its used a lot, a lot of wierd memory problems occur.



    Also I tried:
    Code:
    void function()
    {
        int* thing = 0;
        int size = 0;
    
        while(# of iterations)
        {
            someFunction(thing, &size);
    
            someOtherFunction(thing);
        }
    
    }
    
    void someFunction(int* thing, int*size)
    {
        if(somethingHappens)
        {
            if(*size == 0)
                  thing = (int*)malloc(sizeof(int));
            else
                   thing = (int*)realloc(thing, sizeof(int) * (*size + 1));
        
            thing[size] = someData;
            size++;
        }
         
        //other stuff goes here
    }
    But if 'thing' is malloc'd inside someFunction() when the function returns 'thing' is NULL in Function().

    So the only way I actually got it to work without memory problems is to make 'thing'
    global, but it seems like a very unelegant solution. Is there a better way to do this?

  2. #2
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    You can't change the value of a variable in a caller from the called function. Case in point:

    Code:
    int caller(void)
    {
        int x = 5;
        called(x);
        printf("&#37;d\n", x);
    }
    
    int called(int x)
    {
        x = 10;
    }
    Assuming main() calls caller(), then the result will be 5, not 10. I'm sure you probably know this, but you're not applying this to pointers.

    If you pass a pointer to a function, you can't change its value from another function, just like any variable. If x was a pointer in my example, then you still have the same problem. x in caller() will always be 5 (or whatever original assigned value).

    To get around it, you have to pass a pointer to that type, which in your case is a pointer to a pointer to an int.

    Simple put:

    • To alter an int, you must pass in an int *.
    • To alter an int *, you must pass in an int **.
    • To alter an int **, you must pass in an int ***.


    And of course, by "alter" I mean changing its value in the caller function from a called function.

  3. #3
    Registered User
    Join Date
    Dec 2007
    Posts
    15
    I'm having a hard time coming up with the code. Could you please give me an example?

  4. #4
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    Example of what?

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    void setp(int **);
    
    void setp(int **q)
    {
    	*q = malloc(sizeof(**q));
    	if(!*q)
    	{
    		fprintf(stderr, "No memory....");
    		return;
    	}
    	printf("Enter an int: ");
    	fflush(stdout);
    	scanf("&#37;d", *q);
    }
    
    int main(void)
    {
    	int *p = NULL;
    	
    	setp(&p);	/* Note:  Passing the ADDRESS of p */
    	if(p)
    	{
    		printf("You entered: %d\n", *p);
    		free(p);
    	}
    	
    	return 0;
    }
    In order to change what p points to in main() from setp(), you have to pass the address of p to setp().

  5. #5
    Registered User ssharish2005's Avatar
    Join Date
    Sep 2005
    Location
    Cambridge, UK
    Posts
    1,732
    Quote Originally Posted by alwut View Post
    I'm having a hard time coming up with the code. Could you please give me an example?
    Here is a sample code.

    Code:
    #include <stdio.h>
    #include <stdlib.h>
    
    int * allocate(int *);
    int rellallocate(int **);
    
    int main()
    {
        int *array, i;
            
        if( ( array = allocate(array) ) != NULL )
        {
            printf("Memory allocated\n");
            printf("-~-~-~-~-~-~-~-~\n");
            
            for(i=0; i<20; i++)
               printf("&#37;d\t", array[i]);
            
            free(array);
        }
        else
            printf("Allocation failed\n");
        
        getchar();
        return 0;
    }
    
    int * allocate(int *array)
    {
        int i;
        
        if( ( array = malloc( sizeof(int) * 10 ) ) != NULL )
        {
            for(i=0; i < 10; i++ )
               array[i] = i+1;
            
            if( rellallocate(&array) )
            {
                for(; i < 20; i++)
                   array[i] = i+1;
            }
            else
                return NULL;            
        }
        else
            return NULL;
        
        return array;
    }
    
    int rellallocate(int **array)
    {
        int **Extra;
        
        if( ( Extra = realloc( *array, sizeof(int) * 20  ) ) != NULL )
        {
            array = Extra;
            return 1;
        }
        else
            return 0;
    }
    
    /* my output
    Memory allocated
    -~-~-~-~-~-~-~-~
    1       2       3       4       5       6       7       8       9       10
    11      12      13      14      15      16      17      18      19      20
    */
    Note: The way I send the pointer between the functions and how to call the realloc function.

    ssharish

  6. #6
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,660
    If you need to modify a variable in another function, you need a pointer to it (or you return it by value, as malloc does).

    Eg.
    Code:
    void function()
    {
        int* thing = 0;
        int size = 0;
    
        while(# of iterations)
        {
            someFunction(&thing, &size);
    
            someOtherFunction(thing);
        }
    
    }
    
    void someFunction(int** thing, int*size)
    {
        if(somethingHappens)
        {
            if(*size == 0)
                *thing = malloc(sizeof(int));
            else {
                void *temp = realloc(thing, sizeof(int) * (*size + 1));
                if ( temp != NULL ) {
                    *thing = temp;
                } else {
                    /* oops, we can't expand, but thing is still VALID memory */
                }
            }
            (*thing)[size] = someData;
            (*size)++;
        }
         
        //other stuff goes here
    }

    Oh, and see the FAQ on casting malloc.

    Also note the safe way of calling realloc which deals with the failure to expand the memory.
    If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
    If at first you don't succeed, try writing your phone number on the exam paper.

  7. #7
    Registered User
    Join Date
    Dec 2007
    Posts
    15
    Thank you all for your quick responses, the code everyone posted was extremely helpful.

    But i'm getting a weird error, I don't know if its me or something but when I try it with a 2-D pointer it won't malloc because the pointer is a null pointer if that makes any sense.

    Heres a generic version of code.

    Code:
    void function()
    {
        int** thing = 0;
        int size = 0;
    
        while(# of iterations)
        {
            someFunction(&thing, &size);
    
            someOtherFunction(thing);
        }
    
    }
    
    void someFunction(int*** thing, int*size)
    {
        if(somethingHappens)
        {
            if(*size == 0)
                //it dies here the first time reaches this statement
                **thing = malloc(sizeof(int));
            else 
                **thing = realloc(thing**,sizeof(int))*(*size+1);
        }
         
        //other stuff goes here
    }
    Any thoughts?

  8. #8
    Deathray Engineer MacGyver's Avatar
    Join Date
    Mar 2007
    Posts
    3,210
    All you did was just add extra stars everywhere. That won't get you anywhere. Look at Salem's example again.

    And why are you confused as to why it's failing? Look at your code. You're passing in the address of the variable size. Size has a given value of 0. Then you're checking what value is in the location pointed to the address of size (which is simply the value of size!). Well for crying out loud, you just set it to 0... lol.

  9. #9
    Registered User
    Join Date
    Aug 2005
    Location
    Austria
    Posts
    1,990
    Code:
    **thing = malloc(sizeof(int));
    You just know that *thing points to NULL
    you don't know where **thing points to.

    try something like

    Code:
    *thing = malloc( size * sizeof( int* ));
    for ( i = 0; i < size, ++i  )
        *(thing[i])=malloc(sizeof(int));
    Kurt

  10. #10
    Registered User
    Join Date
    Dec 2007
    Posts
    15
    Ok I got it to work now. Thanks a lot. I was just confused and thought there was whole pattern to passing in pointers. ZuK, your example was perfect.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. sorting number
    By Leslie in forum C Programming
    Replies: 8
    Last Post: 05-20-2009, 04:23 AM
  2. Undefined Reference Compiling Error
    By AlakaAlaki in forum C++ Programming
    Replies: 1
    Last Post: 06-27-2008, 11:45 AM
  3. Screwy Linker Error - VC2005
    By Tonto in forum C++ Programming
    Replies: 5
    Last Post: 06-19-2007, 02:39 PM
  4. Passing pointer into function bug
    By CodeMonkey in forum C++ Programming
    Replies: 4
    Last Post: 04-26-2005, 11:13 PM
  5. Interface Question
    By smog890 in forum C Programming
    Replies: 11
    Last Post: 06-03-2002, 05:06 PM