This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

NULL peculiarities

I have a question about the behavior of some code I have written:

Packet Packet_str;

when I declare this structure in my main program and then check its memory location via a printf statement and hyperterminal it says it is 0000. This seems to cause problems in the program I am guessing that something thisnk that this is NULL, but... when i check to see if it is NULL or even (void *) 0 it is false but is true only when I check if it is 0x0000. One way I have been able to get around this is to create a variable which i do not use simply to make Packet_str at a different address than 0000. I have included the following code to help better understand my problem.

Packet_str gets passed to this function which uses it under the var name MyPacI. Buffer is an unsigned char * in the Packet structure. Also Packet_str is passed in by reference.

if( MyPacI->Buffer == NULL)/*false*/
printf("1:Unable to malloc memory!\n");
else if(MyPacI->Buffer == (void *) 0)/*false*/
printf("2:Unable to malloc memory!\n");
else if(MyPacI->Buffer == 0x0000)/*true*/
printf("3:Unable to malloc memory!\n");

the above is true when I do not make the dummy variable in main. If I make a Packet *dummy variable it offsets the Packet_str to memory location 0003 and all works correctly, but... if in main I set dummy = NULL it acts as if I never created the dummy variable. I only set dummy to NULL to avoid optimization on other compilers. It is not needed under keil. In short I am wondering why this all happens. Why do functions assume 0000 = NULL but not vise-versa, and is there another way to make Packet_str not be at address 0000 other than making an unused variable?

Parents

  • The cast from a specific pointer to a generic pointer should work. Essentially, the code should just insert the tag byte for xdata along with value of the xdata*. I'd expect to see assembly code along the lines of

        CALL    _malloc
        MOV     R2,AR6
        MOV     R1,AR7
        MOV     R3,#01H
    

    In this case, R3 is the tag byte, and just gets assigned an immediate constant value of 1 (xdata).

    (It's curious that Keil flips the endianness to a little-endian order in the register allocation for generics. But what the heck; as long as they can keep track.)

    Casting the other way, generic to specific, could be dangerous unless you're sure the generic pointer really points to the right memory area.

    (Hm. That's my second C++ flashback of the thread. First, it's comparing pointers directly to 0 instead of ((void*)0). Now, we've got the problem of casting to a subclass. All we need is dynamic_cast<xdata*>...)

    The supplied code for malloc() returns a "void _MALLOC_MEM_ *". The supplied stdlib.h #defines _MALLOC_MEM_ as "xdata", so I'd expect the out-of-the-box malloc() would indeed return a void xdata* instead of a void*.

Reply

  • The cast from a specific pointer to a generic pointer should work. Essentially, the code should just insert the tag byte for xdata along with value of the xdata*. I'd expect to see assembly code along the lines of

        CALL    _malloc
        MOV     R2,AR6
        MOV     R1,AR7
        MOV     R3,#01H
    

    In this case, R3 is the tag byte, and just gets assigned an immediate constant value of 1 (xdata).

    (It's curious that Keil flips the endianness to a little-endian order in the register allocation for generics. But what the heck; as long as they can keep track.)

    Casting the other way, generic to specific, could be dangerous unless you're sure the generic pointer really points to the right memory area.

    (Hm. That's my second C++ flashback of the thread. First, it's comparing pointers directly to 0 instead of ((void*)0). Now, we've got the problem of casting to a subclass. All we need is dynamic_cast<xdata*>...)

    The supplied code for malloc() returns a "void _MALLOC_MEM_ *". The supplied stdlib.h #defines _MALLOC_MEM_ as "xdata", so I'd expect the out-of-the-box malloc() would indeed return a void xdata* instead of a void*.

Children
No data