Thread: pointer as a parameter and/or casting bug

  1. #1
    Registered User
    Join Date
    Mar 2005
    Posts
    4

    pointer as a parameter and/or casting bug

    I'll admit that I feel like a bit of a dummy not knowing C syntax too well, and I'm writing code for an operating systems class. Syntax problems aren't what I should be getting stuck on, but I'm stuck right now. Here's code for one of our functions:
    Code:
    void wait(sysargs *args)
    {
    int temp = 0;
    int k_pid = 0;
    
    k_pid = join(&temp);
    
    args->arg1 = (void *)k_pid;
    args->arg2 = (void *)temp;
    
    if(k_pid == -2)
    args->arg4 = (void *)-1;
    else
    args->arg4 = (void *)0;
    
    printf("wait joined with %d\n", (int)args->arg1);
    printf("wait staus was %d\n", (int)args->arg2);
    }
    For reference sysargs is a structure that looks like:
    Code:
    typedef struct sysargs
    {
    int number;
    void *arg1;
    void *arg2;
    void *arg3;
    void *arg4;
    void *arg5;
    } sysargs;
    At the print statements at the bottom, we get the correct output. However, when the function that called this one returns, and tries to use the values we stored in args, they're not the right values (i.e. instead of 5, we get 74600).

    What are we doing wrong with how we store the values? Do we need to use memcpy, or are we casting incorrectly, or what?

  2. #2
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Well for starters, you haven't allocated any memory for any of the pointers in your structure. You're just randomly assigning values to pointers. What you're also doing wrong is ignoring your compiler's warnings.

    Quzah.
    Hope is the first step on the road to disappointment.

  3. #3
    Registered User
    Join Date
    Mar 2005
    Posts
    4
    Quote Originally Posted by quzah
    Well for starters, you haven't allocated any memory for any of the pointers in your structure. You're just randomly assigning values to pointers.
    Another function creates a sysargs variable, and makes the call to this function.. so I'm not sure what you mean.

    Quote Originally Posted by quzah
    What you're also doing wrong is ignoring your compiler's warnings.
    There are no warnings, and we're compiling with gcc -Wall

  4. #4
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    Code:
    void wait(sysargs *args)
    {
        int temp = 0;
        int k_pid = 0;
    
        k_pid = join(&temp);
    
        args->arg1 = (void *)k_pid; /* assign a garbage value to a pointer */
        args->arg2 = (void *)temp; /* now do it again */
    
        if(k_pid == -2)
            args->arg4 = (void *)-1; /* and again */
        else
            args->arg4 = (void *)0; /* and again, which is in effect, NULL, to a pointer */
    
        printf("wait joined with %d\n", (int)args->arg1);
        printf("wait staus was %d\n", (int)args->arg2);
    }
    Basicly what you do is just assign a bunch of bogus values to pointers. See pointers are just like other variables. They store values. However, the value a pointer stores is a memory address, so assigning -1 to one, or 0, or whatever else, is wrong.

    All of these assignments are wrong. You assign memory addresses to pointers. Not pure values.

    Yes, your compiler is complaining. Or rather, if you hadn't of gagged it, it would. You "worked around" the warnings by typecasting everything to a void pointer. Go on, remove all the typecasts. Now listen to your compiler.

    You don't typecast to void assignments. There's no point in doing so, other than to hide what your compiler is trying to tell you.

    Quzah.
    Hope is the first step on the road to disappointment.

  5. #5
    Registered User
    Join Date
    Mar 2005
    Posts
    4
    Okay, I think I understand what you're getting at.

    We casted to void pointers, because that's the type that those variables are. We are using them so that we can store a variety of different types of information in the sysargs struct, so that it can be used for different types of function calls.

    If I remove the casts to void *, and do something like
    args->arg2 = &k_pid;

    That has the same effect.

    So instead of mocking me for not having a full grasp of what's going on, can you try and help me out? I already know that what the code is doing is wrong.

    I just would like to know what I should do to get the correct behavior. i.e. should I be using memcpy, maybe?

  6. #6
    ATH0 quzah's Avatar
    Join Date
    Oct 2001
    Posts
    14,826
    I just told you what's wrong. You're just not paying attention, or you don't like my answer. Either way, the end result is the same. As a matter of fact, I told you in my first post what was wrong. Let's review:
    Quote Originally Posted by quzah
    Well for starters, you haven't allocated any memory for any of the pointers in your structure. You're just randomly assigning values to pointers.
    So, once again, if you actually plan on having those be useable, you need to allocate memory dynamicly and assign values to that. Since you apparently either don't know how, or are just acting like it, here's how:
    Code:
    struct foo
    {
        void *bar;
    };
    
    void baz( struct foo *f )
    {
        f->bar = malloc( sizeof( whateverdatatypeyouwant ) * howevermanyyouwant );
        if( f->bar == NULL )
        {
            printf("malloc failed\n");
            return;
        }
        ...else do something with whatever it is you're doing...
    }
    To further illustrate, let's pretend we only want 1 integer allocated. Then we want to assign it a value. This stuff should be stuck in the passed structure foo:

    Code:
    void baz( struct foo *f )
    {
        f->bar = malloc( sizeof( int );
        if( f->bar == NULL )
        {
            printf("malloc failed\n");
            return;
        }
    
        f->bar = 10; /* assign the value of 10 into the newly allocated int */
    }
    
    ...stuff...
    
    int main( void )
    {
        struct foo instance;
    
        baz( &instance );
        if( instance.bar == NULL )
        {
            printf("malloc failed inside of baz\n");
        }
        else
        {
            printf("the value of instance.bar is %d", *instance.bar );
            free( instance.bar );
        }
    
        return 0;
    }
    Now go read up on functions like malloc and free.

    Quzah.
    Hope is the first step on the road to disappointment.

  7. #7
    Registered User
    Join Date
    Mar 2005
    Posts
    4
    Now I feel really stupid. We were restricted from using malloc in earlier parts of our code, as we were initializing process tables etc. and malloc is not supposed to exist at that point, so we couldn't use it - and instead had to allocate memory dynamically.

    Anyways, yes - we can use malloc now and it just completely got blocked out of my mind as an option after spending lots of time doing the other code. So thanks for bringing me back to reality.

    You were kind of an ass in the way you responded, but whatever. That's the internet, and that's message boards for ya. I'm over it.

  8. #8
    ---
    Join Date
    May 2004
    Posts
    1,379
    using malloc IS allocating dynamically

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 5
    Last Post: 04-04-2009, 03:45 AM
  2. Replies: 0
    Last Post: 03-20-2008, 07:59 AM
  3. Compiler "Warnings"
    By Jeremy G in forum A Brief History of Cprogramming.com
    Replies: 24
    Last Post: 04-24-2005, 01:09 PM
  4. Request for comments
    By Prelude in forum A Brief History of Cprogramming.com
    Replies: 15
    Last Post: 01-02-2004, 10:33 AM
  5. function pointer & Thread Parameter :: Multithreading
    By kuphryn in forum Windows Programming
    Replies: 3
    Last Post: 09-11-2002, 08:42 AM