Thread: Casting short to char*

  1. #1
    Registered User
    Join Date
    Aug 2006
    Posts
    68

    Casting short to char*

    Hi fellows!

    I am dealing with raw data and want to interpret data within an array differently.

    Code:
    unsigned char data[] = "\x99\xA2\x1E\x00\x6B\x00\xE4\x03\x00\x00\x00..."
    printf("%hu\n", (unsigned short)data[0]);
    Output: 153 instead of 41625.

    I thought I finally understood the fine things you can do with casting but in real I don't :S

    So from the first 2 bytes of the byte array I want to get an unsigned short/word. The next data I interpret as raw byte data. Somewhere in the data I have strings and some integers also.

    What am I doing wrong?
    Last edited by Hawkin; 02-02-2011 at 10:21 PM.

  2. #2
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    data[0] is not two bytes of the byte array. It is one byte of the byte array.

    Interpreting two bytes of an array as a short will depend on your endianness. If you want data[0] to be the high byte and data[1] to be the low byte, then just do
    Code:
    data[0]<<8+data[1]
    Unless, of course, you intend to use the endianness for all its glory; in that case, you would want to reinterpret the pointer (not the thing pointed to, but the pointer itself -- once you dereference the pointer with the old data type, it's game over) as a pointer to the new type.

  3. #3
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Thanks for the answer.

    I just found in some of my old code that I had already solved this problem.
    As you said, I may only do it with a new pointer.

    I also saw that I had to live with the compiler warnings ([Warning] initialization from incompatible pointer type) due to it.

    Code:
    unsigned short* data2 = data+3;
    printf("%hu\n", *data2);
    Output: 27392 (0x6B00)

    It's works perfectly like this but I have tons of compiler warnings in my old projects. At some point it was difficult telling new warnings apart from the old ones and debugging became a hassle :S

    And I have no choice about the endianness. This is the raw data I receive, this is the raw data I have to work with.

  4. #4
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    Quote Originally Posted by Hawkin View Post
    I also saw that I had to live with the compiler warnings ([Warning] initialization from incompatible pointer type) due to it.
    That's what casts are for.
    Code:
    short *newpointer = (short *)whatever;

  5. #5
    Registered User
    Join Date
    Dec 2010
    Posts
    31
    You can convince the compiler you know what you're doing by using a cast
    Code:
              unsigned short* data2 = (unsigned short *)data+3;

  6. #6
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    I have another issue...

    Code:
    int *a = malloc(0);
    
    int foo(int* array)
    {
    
    int *temp = malloc(0); temp = (int*) realloc(array, somenumber*sizeof(int)); if(temp != NULL) array = temp; else return -2;
    } //edit: I forgot: foo(a);
    I don't understand, that when the location of 'array' changes, why the location of 'a' does not change too. It just doesn't want to go into my brain. Can I only achieve changing 'a' by using it as a global pointer?
    Last edited by Hawkin; 02-03-2011 at 08:29 AM.

  7. #7
    C++ Witch laserlight's Avatar
    Join Date
    Oct 2003
    Location
    Singapore
    Posts
    28,413
    Quote Originally Posted by Hawkin
    I don't understand, that when the location of 'array' changes, why the location of 'a' does not change too. It just doesn't want to go into my brain. Can I only achieve changing 'a' by using it as a global pointer?
    If you are trying to change a from a function, then you need to pass a pointer to a, i.e., the function parameter must be a pointer to a pointer.
    Quote Originally Posted by Bjarne Stroustrup (2000-10-14)
    I get maybe two dozen requests for help with some sort of programming or design problem every day. Most have more sense than to send me hundreds of lines of code. If they do, I ask them to find the smallest example that exhibits the problem and send me that. Mostly, they then find the error themselves. "Finding the smallest program that demonstrates the error" is a powerful debugging tool.
    Look up a C++ Reference and learn How To Ask Questions The Smart Way

  8. #8
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    > It's works perfectly like this but I have tons of compiler warnings in my old projects
    Yeah, and then the bad news starts - it crashes when you port it to a new machine.

    Why?
    > unsigned short* data2 = data+3;
    In this example, you added an odd number, most likely making data2 an odd address.
    But many machines do not allow you to access wider data types on odd addresses. What you get in return (in Unix/Linux terms) is a bus error.

    > This is the raw data I receive, this is the raw data I have to work with.
    Then you should do as tabstop suggested in post #2
    It is the only reliable way of safely reassembling your input byte stream into data you can understand.
    It works no matter what endian your host machine is, and there is no dodgy casting of pointer types either.
    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.

  9. #9
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    laserlight: And exactly there is my problem in understanding.

    Code:
    int *a = malloc(0);
    
    int foo(int** array)
    {
    
    int *temp = malloc(0); temp = (int*) realloc(array, somenumber*sizeof(int)); if(temp != NULL) *array = temp; else return -2; //Do stuff...
    } //edit: I forgot: foo(&a);
    I think it might have something to do with *array being array[0], but no I don't understand, why a[0] becomes the address of a (&a) and what to do to make it work as intended.

    a[0] = 2358913;
    a[1] = 1;
    a[2] = 2;
    a[3] = 3;
    ...

    Salem: Does this also apply for unsigned short *data2 = (unsigned short*)(data+3);
    I've been able to run it at several computers (all on windows though), so the only safe way to do it is by calculating the bytes?

  10. #10
    and the hat of int overfl Salem's Avatar
    Join Date
    Aug 2001
    Location
    The edge of the known universe
    Posts
    39,659
    If your cast comes with a change of alignment, then you're potentially in trouble.
    The problem (for you) at the moment is that you're only testing on x86 processors. This is one that allows you (possibly with a small performance hit) to access mis-aligned data.

    > temp = (int*) realloc(array, somenumber*sizeof(int));
    If your indent is to expand the array, then you need
    temp = realloc(*array, somenumber*sizeof(int));

    > foo(&a);
    If you have
    int *a = NULL;
    int *a = malloc(0); // or some size
    then you're OK.

    If a is some kind of reference to some real array, then you're stuffed.


    > int *temp = malloc(0);
    This is a memory leak, you immediately trash temp.
    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.

  11. #11
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Code:
    int foo(int** array)
    {
    
    int i; for(i = 0; i < 8; i++) {
    int *temp = malloc(0); temp = (int*) realloc(*array, (i+1)*sizeof(int)); if(temp != NULL) *array = temp; else {
    free(temp); return -2;
    } array[i] = (int*) i; printf("%d - %d - %d\n", i, array[i], array); printf("%08X %08X %08X %08X %08X %08X %08X %08X\n", *array, *(array+1), *(array+2), *(array+3), *(array+4), *(array+5), *(array+6), *(array+7)); free(temp);
    }
    } int main() {
    int *a = malloc(0); int g_i; foo(&a); for(g_i = 0; g_i < 8; g_i++)
    printf("%d - %d\n", (int*) a, (int*) a[g_i]);
    }
    Output:
    Code:
    0 - 0 - 0023FF74
    00000000 0023FFB0 004011E7 00000001 00032468 00032B08 00404000 0023FFA4
    1 - 1 - 0023FF74
    000324D0 00000001 004011E7 00000001 00032468 00032B08 00404000 0023FFA4
    2 - 2 - 0023FF74
    000324D0 00000001 00000002 00000001 00032468 00032B08 00404000 0023FFA4
    3 - 3 - 0023FF74
    000324D0 00000001 00000002 00000003 00032468 00032B08 00404000 0023FFA4
    4 - 4 - 0023FF74
    00032508 00000001 00000002 00000003 00000004 00032B08 00404000 0023FFA4
    5 - 5 - 0023FF74
    00032508 00000001 00000002 00000003 00000004 00000005 00404000 0023FFA4
    6 - 6 - 0023FF74
    00032548 00000001 00000002 00000003 00000004 00000005 00000006 0023FFA4
    7 - 7 - 0023FF74
    00032548 00000001 00000002 00000003 00000004 00000005 00000006 00000007
    
    00032548 - 206152
    
    00032548 - 196984
    
    00032548 - 131200
    
    00032548 - 5046350
    
    00032548 - 1599557448
    
    00032548 - 1096041796
    
    00032548 - 1163282770
    
    00032548 - 3818301
    These are my 2 problems. In memory array[0] is never 0. And with applying your fix a[i] does not point to the memory I have written to.

    I am so confused :S

  12. #12
    and the Hat of Guessing tabstop's Avatar
    Join Date
    Nov 2007
    Posts
    14,336
    In foo, array[i] is not a data element -- it is a pointer (if it was anything valid which it isn't really). (*array)[i] are your data elements.

  13. #13
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Oooh in the beginning I tried to convince myself that it's logical for it to be *array[i] and tried it. The result was a crashing program. I would have never found out that it must be (*array)[i]
    Thanks!

    Now the remaining problem stays:

    Output:
    Code:
    ...
    00032550 - 206160
    
    00032550 - 197976
    
    00032550 - 2
    
    00032550 - 3
    
    00032550 - 4
    
    00032550 - 5
    
    00032550 - 6
    
    00032550 - 7
    So why is a[0] and a[1] not 0 and 1?

  14. #14
    Registered User
    Join Date
    Nov 2010
    Location
    Long Beach, CA
    Posts
    5,909
    Quote Originally Posted by Hawkin View Post
    Code:
    int foo(int** array)
    {
    
    int i; for(i = 0; i < 8; i++) {
    int *temp = malloc(0); temp = (int*) realloc(*array, (i+1)*sizeof(int)); if(temp != NULL) *array = temp; else {
    free(temp); return -2;
    } array[i] = (int*) i; printf("%d - %d - %d\n", i, array[i], array); printf("%08X %08X %08X %08X %08X %08X %08X %08X\n", *array, *(array+1), *(array+2), *(array+3), *(array+4), *(array+5), *(array+6), *(array+7)); free(temp);
    }
    } int main() {
    int *a = malloc(0); int g_i; foo(&a); for(g_i = 0; g_i < 8; g_i++)
    printf("%d - %d\n", (int*) a, (int*) a[g_i]);
    }
    I don't know how this worked for you. Luck, maybe. I first made what I think are all the appropriate (*array)[i] changes tabstop mentioned, but my program crashed on that free call. Since temp and *array point to the same place, when you free temp, you are effectively freeing *array too, which means the realloc wont work, except by sheer, magical coincidence. Once I removed that free, I seemed to have a working program.

  15. #15
    Registered User
    Join Date
    Aug 2006
    Posts
    68
    Wow I got a good portion of dumbness
    Thanks, this is the big mistakes, I totally didn't think about it.

    Well, day ended, I've learned couple of things. Thanks guys!

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Casting pointer to unsigned short
    By cks2k2 in forum C Programming
    Replies: 6
    Last Post: 03-25-2009, 05:33 AM
  2. Accessing Structures Inside Structures
    By Mellowz in forum C Programming
    Replies: 1
    Last Post: 01-13-2008, 03:55 AM
  3. Help calling function is asm
    By brietje698 in forum C++ Programming
    Replies: 24
    Last Post: 12-06-2007, 04:48 PM
  4. Say what? - Weird error.
    By Blackroot in forum C++ Programming
    Replies: 6
    Last Post: 08-15-2006, 11:54 PM
  5. Color Variety
    By Unregistered in forum C++ Programming
    Replies: 7
    Last Post: 10-23-2002, 09:17 AM