Understand piece of code.....

Discussion in 'C Programming' started by Terry Andersen, Jul 29, 2003.

  1. Could anyone please help me understand what is going on in the code below. A
    short explanation would be nice.....

    Best Regards
    Terry

    struct mystruct {
    unsigned char testchar;
    unsigned short testshort;
    unsigned char anothertestchar;
    };



    void testfunc(unsigned char* mymemlocation) {

    struct mystruct *thedata = (struct mystruct*) mymemlocation;

    thedata->testchar = 0x55;
    thedata->testshort = 0xFFFF;
    thedata->anothertestchar = 0x11;

    }
     
    Terry Andersen, Jul 29, 2003
    #1
    1. Advertising

  2. Terry Andersen

    Greg P. Guest

    "Terry Andersen" <> wrote in message
    news:bg59q7$veg$-c.dk...
    > struct mystruct {
    > unsigned char testchar;
    > unsigned short testshort;
    > unsigned char anothertestchar;
    > };

    You have created a structure, which is something like a container for
    arbitrary types and related variables.

    > void testfunc(unsigned char* mymemlocation) {
    >
    > struct mystruct *thedata = (struct mystruct*) mymemlocation;

    This is a function that passes a pointer for a memory location to store your
    struct. This is _nasty code_. Never assume that unsigned char* is equal to
    anything else but unsigned char. The parameter should be void*
    mymemlocation. Most likely, this function is requiring that you supply your
    own allocated pointer for manipulation of the structure on the heap.

    > thedata->testchar = 0x55;

    Pointers use -> or (*struct). to access members if they are pointers.
    Otherwise they use a period '.'. This line here sets testchar to the letter
    'U', which is 0x55 in hexadecimal. 0x before a value indicates that it is
    hexadecimal. You could have also made it equal to 85.

    > thedata->testshort = 0xFFFF;

    This sets testshort, the unsigned short int from the structure, to 65535.

    > thedata->anothertestchar = 0x11;

    This sets the other character to 17, which is an unprintable (not
    alpha-numeric) digit.

    > }

    There should be a semicolon here.
     
    Greg P., Jul 29, 2003
    #2
    1. Advertising

  3. "Greg P." <> wrote in message
    news:eek:cqVa.1607$...
    > "Terry Andersen" <> wrote in message
    > news:bg59q7$veg$-c.dk...
    > > struct mystruct {
    > > unsigned char testchar;
    > > unsigned short testshort;
    > > unsigned char anothertestchar;
    > > };

    > You have created a structure, which is something like a container for
    > arbitrary types and related variables.
    >
    > > void testfunc(unsigned char* mymemlocation) {
    > >
    > > struct mystruct *thedata = (struct mystruct*) mymemlocation;

    > This is a function that passes a pointer for a memory location to store

    your
    > struct. This is _nasty code_. Never assume that unsigned char* is equal to
    > anything else but unsigned char. The parameter should be void*
    > mymemlocation. Most likely, this function is requiring that you supply

    your
    > own allocated pointer for manipulation of the structure on the heap.
    >
    > > thedata->testchar = 0x55;

    > Pointers use -> or (*struct). to access members if they are pointers.
    > Otherwise they use a period '.'. This line here sets testchar to the

    letter
    > 'U', which is 0x55 in hexadecimal. 0x before a value indicates that it is
    > hexadecimal. You could have also made it equal to 85.
    >
    > > thedata->testshort = 0xFFFF;

    > This sets testshort, the unsigned short int from the structure, to 65535.
    >
    > > thedata->anothertestchar = 0x11;

    > This sets the other character to 17, which is an unprintable (not
    > alpha-numeric) digit.
    >
    > > }

    > There should be a semicolon here.
    >
    >


    Thanks a lot. Would this mean that testchar, testshort and anothertestchar
    are stored from memory location mymemlocation and further? If mymemlocation
    would be like:

    unsigned char TheBuffer[100];
    //and you called the testfunc with:

    testfunc(TheBuffer[50]);

    /*
    Would TheBuffer then look like:
    TheBuffer[50] = 0x55
    TheBuffer[51] = 0xFF
    TheBuffer[52] = 0xFF
    TheBuffer[53] = 0x11
    ???
    */

    Best Regards
    Terry
     
    Terry Andersen, Jul 29, 2003
    #3
  4. Terry Andersen

    Greg P. Guest

    "Terry Andersen" <> wrote in message
    news:bg5c27$fr$-c.dk...
    > Thanks a lot. Would this mean that testchar, testshort and anothertestchar
    > are stored from memory location mymemlocation and further? If

    mymemlocation
    > would be like:
    >
    > unsigned char TheBuffer[100];
    > //and you called the testfunc with:
    >
    > testfunc(TheBuffer[50]);

    No. First of all you would not pass TheBuffer to testfunc() with the
    subscript on it. It would be passed as

    testfunc(TheBuffer);

    instead. The name of an array is a pointer to the first value, which you
    could later iterate over.

    > Would TheBuffer then look like:
    > TheBuffer[50] = 0x55
    > TheBuffer[51] = 0xFF
    > TheBuffer[52] = 0xFF
    > TheBuffer[53] = 0x11

    No. I think you mean: would the buffer[index] hold the values from the
    function as array indexes. No.

    With this code, you are now overwriting the boundary of your array, which
    ends at 49. Remember that arrays start from 0, and go to length-1. So if I
    had an array like:

    char array[45];

    I can only access array[0] to array[44].

    If you access anything outside of your array's range, it is undetermined
    behavior, but most likely you will overwrite another program's (running on
    your machine) data causing a crash or something nastier.

    To get back to your question about whether the members from the struct are
    part of the array, no. You are attempting to pass an unsigned char to your
    function as a form of memory reservation. Instead use:

    struct mystruct p_yourstruct* = (struct mystruct) malloc(sizeof(mystruct));

    to get the memory. For example:
    ---------------------------------------------
    struct mystruct
    {
    unsigned char testchar;
    unsigned short testshort;
    unsigned char anothertestchar;
    };

    struct mystruct* mem_location = (struct mystruct) malloc(sizeof(mystruct));

    void testfunc(struct mystruct* mymemlocation)
    {
    thedata->testchar = 0x55;
    thedata->testshort = 0xFFFF;
    thedata->anothertestchar = 0x11;
    };
    -----------------------------------------------------------------------
    malloc() allocates memory for your struct. You need to call
    free(mem_location) to free up the memory before your program terminates, or
    else you will get memory leak.

    To use the code you would pass:

    testfunc(mem_location);

    and then you could goof off with the variables.

    Try not to mix apples and oranges. The only thing you should pass to hold a
    struct is another struct of the same type. It would be like passing a car
    variable to a function that uses the car to hold a mansion.

    Any more questions? =)
     
    Greg P., Jul 29, 2003
    #4
  5. "Greg P." <> wrote in message
    news:RNqVa.1621$...
    > "Terry Andersen" <> wrote in message
    > news:bg5c27$fr$-c.dk...
    > > Thanks a lot. Would this mean that testchar, testshort and

    anothertestchar
    > > are stored from memory location mymemlocation and further? If

    > mymemlocation
    > > would be like:
    > >
    > > unsigned char TheBuffer[100];
    > > //and you called the testfunc with:
    > >
    > > testfunc(TheBuffer[50]);

    > No. First of all you would not pass TheBuffer to testfunc() with the
    > subscript on it. It would be passed as
    >
    > testfunc(TheBuffer);
    >
    > instead. The name of an array is a pointer to the first value, which you
    > could later iterate over.
    >
    > > Would TheBuffer then look like:
    > > TheBuffer[50] = 0x55
    > > TheBuffer[51] = 0xFF
    > > TheBuffer[52] = 0xFF
    > > TheBuffer[53] = 0x11

    > No. I think you mean: would the buffer[index] hold the values from the
    > function as array indexes. No.
    >
    > With this code, you are now overwriting the boundary of your array, which
    > ends at 49. Remember that arrays start from 0, and go to length-1. So if I
    > had an array like:
    >
    > char array[45];
    >
    > I can only access array[0] to array[44].
    >
    > If you access anything outside of your array's range, it is undetermined
    > behavior, but most likely you will overwrite another program's (running on
    > your machine) data causing a crash or something nastier.
    >
    > To get back to your question about whether the members from the struct are
    > part of the array, no. You are attempting to pass an unsigned char to your
    > function as a form of memory reservation. Instead use:
    >
    > struct mystruct p_yourstruct* = (struct mystruct)

    malloc(sizeof(mystruct));
    >
    > to get the memory. For example:
    > ---------------------------------------------
    > struct mystruct
    > {
    > unsigned char testchar;
    > unsigned short testshort;
    > unsigned char anothertestchar;
    > };
    >
    > struct mystruct* mem_location = (struct mystruct)

    malloc(sizeof(mystruct));
    >
    > void testfunc(struct mystruct* mymemlocation)
    > {
    > thedata->testchar = 0x55;
    > thedata->testshort = 0xFFFF;
    > thedata->anothertestchar = 0x11;
    > };
    > -----------------------------------------------------------------------
    > malloc() allocates memory for your struct. You need to call
    > free(mem_location) to free up the memory before your program terminates,

    or
    > else you will get memory leak.
    >
    > To use the code you would pass:
    >
    > testfunc(mem_location);
    >
    > and then you could goof off with the variables.
    >
    > Try not to mix apples and oranges. The only thing you should pass to hold

    a
    > struct is another struct of the same type. It would be like passing a car
    > variable to a function that uses the car to hold a mansion.
    >
    > Any more questions? =)


    Seems like I have much to learn when programming C.... :)
    What I would like my code to do is what I described, namely I would like to
    "update" part of a global array with the struct data.......what if I called
    testfunc like: testfunc(TheBuffer+50); would'nt I get the desired result
    then? I Mean:

    TheBuffer[50] = 0x55
    TheBuffer[51] = 0xFF
    TheBuffer[52] = 0xFF
    TheBuffer[53] = 0x11

    Or is this a silly way of doing this.....?

    Best Regards
    Terry
     
    Terry Andersen, Jul 29, 2003
    #5
  6. Terry Andersen

    Greg P. Guest

    "Terry Andersen" <> wrote in message
    news:bg5fgf$1k0$-c.dk...
    > Seems like I have much to learn when programming C.... :)
    > What I would like my code to do is what I described, namely I would like

    to
    > "update" part of a global array with the struct data.......what if I

    called
    > testfunc like: testfunc(TheBuffer+50); would'nt I get the desired result
    > then? I Mean:
    >
    > TheBuffer[50] = 0x55
    > TheBuffer[51] = 0xFF
    > TheBuffer[52] = 0xFF
    > TheBuffer[53] = 0x11
    >
    > Or is this a silly way of doing this.....?

    Silly =)

    If you want to update a global array with the values, you would have to call
    your function testfunc() first, properly, then do something like.

    TheBuffer[50] = your_struct->testchar;
    TheBuffer[51] = your_struct->anothertextchar;

    Do not put the unsigned short into the buffer, unless you are sure of its
    value being within range of a byte, which is not likely. You will truncate
    (round off) the value if you try to cast it as a char.

    Also, you keep trying to pass an array of chars to testfunc(), which
    manipulates a structure. No no no <slaps hand>. struct->testchar, testshort,
    and anothertestchar have nothing to do with TheBuffer. You are assuming that
    the compiler puts the value of testchar into TheBuffer[50], the value of
    testshort into TheBuffer[51], and the value of anothertestchar into
    TheBuffer[52]. This is not true. The compiler puts the values into the
    structure, which you can then put into the array.

    What books are you reading on C?
    --

    Regards,
    Greg P.

    Golden Rule of Open Source Programming:
    "Don't whine about something unless you plan to implement it yourself"
     
    Greg P., Jul 29, 2003
    #6
  7. Terry Andersen

    Greg P. Guest

    I don't think I am being clear enough. What you need to do, then, is remove
    the mystruct struct and just work on the array.

    void testfunc(unsigned char array[])
    {
    array[50] = something;
    array[51] = something;
    array[52] = something;
    };
     
    Greg P., Jul 29, 2003
    #7
  8. Terry Andersen

    Dan Pop Guest

    In <bg59q7$veg$-c.dk> "Terry Andersen" <> writes:

    >Could anyone please help me understand what is going on in the code below. A
    >short explanation would be nice.....
    >
    >struct mystruct {
    >unsigned char testchar;
    >unsigned short testshort;
    >unsigned char anothertestchar;
    >};
    >
    >void testfunc(unsigned char* mymemlocation) {
    >struct mystruct *thedata = (struct mystruct*) mymemlocation;
    >
    >thedata->testchar = 0x55;
    >thedata->testshort = 0xFFFF;
    >thedata->anothertestchar = 0x11;
    >}


    If you do not understand this code, the right thing to do is to (re)read
    the chapters dealing with structures and pointers in your favourite C
    book. This is very basic C code and you have a big problem if you don't
    understand it.

    The proper type for mymemlocation in standard C is void pointer, but this
    is a minor detail.

    Dan
    --
    Dan Pop
    DESY Zeuthen, RZ group
    Email:
     
    Dan Pop, Jul 29, 2003
    #8
  9. "Dan Pop" <> wrote in message
    news:bg5ml5$1si$...
    > In <bg59q7$veg$-c.dk> "Terry Andersen" <>

    writes:
    >
    > >Could anyone please help me understand what is going on in the code

    below. A
    > >short explanation would be nice.....
    > >
    > >struct mystruct {
    > >unsigned char testchar;
    > >unsigned short testshort;
    > >unsigned char anothertestchar;
    > >};
    > >
    > >void testfunc(unsigned char* mymemlocation) {
    > >struct mystruct *thedata = (struct mystruct*) mymemlocation;
    > >
    > >thedata->testchar = 0x55;
    > >thedata->testshort = 0xFFFF;
    > >thedata->anothertestchar = 0x11;
    > >}

    >
    > If you do not understand this code, the right thing to do is to (re)read
    > the chapters dealing with structures and pointers in your favourite C
    > book. This is very basic C code and you have a big problem if you don't
    > understand it.
    >
    > The proper type for mymemlocation in standard C is void pointer, but this
    > is a minor detail.
    >
    > Dan
    > --
    > Dan Pop
    > DESY Zeuthen, RZ group
    > Email:




    You are both quite right. Back to the books. Thank you very much for your
    time (especially Greg) and effort.
     
    Terry Andersen, Jul 29, 2003
    #9
  10. Terry Andersen

    Richard Bos Guest

    "Terry Andersen" <> wrote:

    [ Bloody 'ell, what a lot of quoting. Out come the scissors... ]

    > "Greg P." <> wrote in message
    > news:RNqVa.1621$...
    > > "Terry Andersen" <> wrote in message
    > > news:bg5c27$fr$-c.dk...
    > > void testfunc(struct mystruct* mymemlocation)
    > > {
    > > thedata->testchar = 0x55;
    > > thedata->testshort = 0xFFFF;
    > > thedata->anothertestchar = 0x11;
    > > };


    > What I would like my code to do is what I described, namely I would like to
    > "update" part of a global array with the struct data.......what if I called
    > testfunc like: testfunc(TheBuffer+50); would'nt I get the desired result
    > then? I Mean:
    >
    > TheBuffer[50] = 0x55
    > TheBuffer[51] = 0xFF
    > TheBuffer[52] = 0xFF
    > TheBuffer[53] = 0x11


    Not necessarily. There may well be holes in the struct, for example for
    alignment purposes. E.g., it could well result in this:

    TheBuffer[50] == 0x55
    TheBuffer[51] == 0xA2 /* Whatever was there before. */
    TheBuffer[52] == 0xFF
    TheBuffer[53] == 0xFF
    TheBuffer[54] == 0x11

    or

    TheBuffer[50] == 0x55
    TheBuffer[51] == 0x55 /* Which happened to be in the register. */
    TheBuffer[52] == 0xFF
    TheBuffer[53] == 0xFF
    TheBuffer[54] == 0x11

    Moreover, if you change

    thedata->testshort = 0xFFFF;

    to

    thedata->testshort = 0x1234;

    you don't know whether it will end up as

    TheBuffer[52] == 0x12
    TheBuffer[53] == 0x34

    TheBuffer[52] == 0x34
    TheBuffer[53] == 0x12

    unless you happen to know the endianness of your computer. And then you
    have to consider that shorts need not be two bytes long... or, indeed,
    that bytes may be 16 or 32 bits long.

    And as a final thought, this could break depending on what you pass to
    the function, because of alignment errors. For example, suppose that
    shorts need to be aligned on even addresses. If you, your struct will
    indeed have a hole in it, as above. Calling testfunc(TheBuffer+50) will
    work, because the short will, as it should, end up on an even address.
    Now consider where that short will be positioned if you call
    testfunc(TheBuffer+51)...

    > Or is this a silly way of doing this.....?


    Not necessarily, but it's a very system-specific one, and details may
    depend on, e.g., the optimisation flags you used to compile your
    program. IOW, it's risky, and it probably isn't quite as useful as you
    think it is.

    Richard
     
    Richard Bos, Jul 29, 2003
    #10
  11. Terry Andersen

    bd Guest

    On Tue, 29 Jul 2003 08:25:56 +0000, Greg P. wrote:

    > "Terry Andersen" <> wrote in message
    > news:bg59q7$veg$-c.dk...
    >> struct mystruct {
    >> unsigned char testchar;
    >> unsigned short testshort;
    >> unsigned char anothertestchar;
    >> };

    > You have created a structure, which is something like a container for
    > arbitrary types and related variables.
    >
    >> void testfunc(unsigned char* mymemlocation) {

    [snip]
    >
    >> }

    > There should be a semicolon here.


    You don't need a semicolon after a function body.

    --
    Freenet distribution not available
    A holding company is a thing where you hand an accomplice the goods while
    the policeman searches you.
     
    bd, Jul 29, 2003
    #11
  12. Terry Andersen

    bd Guest

    On Tue, 29 Jul 2003 11:42:49 +0200, Terry Andersen wrote:

    > "Greg P." <> wrote in message
    > news:RNqVa.1621$...
    >> "Terry Andersen" <> wrote in message
    >> news:bg5c27$fr$-c.dk...
    >> > Thanks a lot. Would this mean that testchar, testshort and

    > anothertestchar
    >> > are stored from memory location mymemlocation and further? If

    >> mymemlocation
    >> > would be like:
    >> >
    >> > unsigned char TheBuffer[100];
    >> > //and you called the testfunc with:
    >> >
    >> > testfunc(TheBuffer[50]);

    >> No. First of all you would not pass TheBuffer to testfunc() with the
    >> subscript on it. It would be passed as
    >>
    >> testfunc(TheBuffer);
    >>
    >> instead. The name of an array is a pointer to the first value, which you
    >> could later iterate over.
    >>
    >> > Would TheBuffer then look like:
    >> > TheBuffer[50] = 0x55
    >> > TheBuffer[51] = 0xFF
    >> > TheBuffer[52] = 0xFF
    >> > TheBuffer[53] = 0x11

    >> No. I think you mean: would the buffer[index] hold the values from the
    >> function as array indexes. No.
    >>
    >> With this code, you are now overwriting the boundary of your array, which
    >> ends at 49. Remember that arrays start from 0, and go to length-1. So if I
    >> had an array like:
    >>
    >> char array[45];
    >>
    >> I can only access array[0] to array[44].
    >>
    >> If you access anything outside of your array's range, it is undetermined
    >> behavior, but most likely you will overwrite another program's (running on
    >> your machine) data causing a crash or something nastier.
    >>
    >> To get back to your question about whether the members from the struct are
    >> part of the array, no. You are attempting to pass an unsigned char to your
    >> function as a form of memory reservation. Instead use:
    >>
    >> struct mystruct p_yourstruct* = (struct mystruct)

    > malloc(sizeof(mystruct));
    >>
    >> to get the memory. For example:
    >> ---------------------------------------------
    >> struct mystruct
    >> {
    >> unsigned char testchar;
    >> unsigned short testshort;
    >> unsigned char anothertestchar;
    >> };
    >>
    >> struct mystruct* mem_location = (struct mystruct)

    > malloc(sizeof(mystruct));
    >>
    >> void testfunc(struct mystruct* mymemlocation)
    >> {
    >> thedata->testchar = 0x55;
    >> thedata->testshort = 0xFFFF;
    >> thedata->anothertestchar = 0x11;
    >> };
    >> -----------------------------------------------------------------------
    >> malloc() allocates memory for your struct. You need to call
    >> free(mem_location) to free up the memory before your program terminates,

    > or
    >> else you will get memory leak.
    >>
    >> To use the code you would pass:
    >>
    >> testfunc(mem_location);
    >>
    >> and then you could goof off with the variables.
    >>
    >> Try not to mix apples and oranges. The only thing you should pass to hold

    > a
    >> struct is another struct of the same type. It would be like passing a car
    >> variable to a function that uses the car to hold a mansion.
    >>
    >> Any more questions? =)

    >
    > Seems like I have much to learn when programming C.... :)
    > What I would like my code to do is what I described, namely I would like to
    > "update" part of a global array with the struct data.......what if I called
    > testfunc like: testfunc(TheBuffer+50); would'nt I get the desired result
    > then? I Mean:
    >
    > TheBuffer[50] = 0x55
    > TheBuffer[51] = 0xFF
    > TheBuffer[52] = 0xFF
    > TheBuffer[53] = 0x11
    >
    > Or is this a silly way of doing this.....?


    A struct may have padding - it could have any number of spaces in between
    valid members that have no defined value (that is, could contain
    anything).
    --
    Freenet distribution not available
    My face is new, my license is expired, and I'm under a doctor's care!!!!
     
    bd, Jul 29, 2003
    #12
  13. "Terry Andersen" <> wrote in message
    news:bg5c27$fr$-c.dk...
    > "Greg P." <> wrote in message
    > news:eek:cqVa.1607$...
    > > "Terry Andersen" <> wrote in message
    > > news:bg59q7$veg$-c.dk...
    > > > struct mystruct {
    > > > unsigned char testchar;
    > > > unsigned short testshort;
    > > > unsigned char anothertestchar;
    > > > };

    > > You have created a structure, which is something like a container for
    > > arbitrary types and related variables.
    > >


    (big snip)

    > Thanks a lot. Would this mean that testchar, testshort and anothertestchar
    > are stored from memory location mymemlocation and further? If

    mymemlocation
    > would be like:
    >
    > unsigned char TheBuffer[100];
    > file://and you called the testfunc with:
    >
    > testfunc(TheBuffer[50]);
    >
    > /*
    > Would TheBuffer then look like:
    > TheBuffer[50] = 0x55
    > TheBuffer[51] = 0xFF
    > TheBuffer[52] = 0xFF
    > TheBuffer[53] = 0x11
    > ???
    > */


    Well, it could, but on many machines that I know about it would be more like

    TheBuffer[50] = 0x55;
    TheBuffer[52] = 0xFF;
    TheBuffer[53] = 0xFF;
    TheBuffer[54] = 0x11;

    as many machines require a short to have an even address.

    Also, the two bytes of the short may be stored in different order on
    different machines.

    -- glen
     
    Glen Herrmannsfeldt, Jul 29, 2003
    #13
  14. Terry Andersen

    Greg P. Guest

    "bd" <-ip.org> wrote in message
    news:p-ip.org...
    > You don't need a semicolon after a function body.


    Right! I was tired, sorry terry.
     
    Greg P., Jul 29, 2003
    #14
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Przemo
    Replies:
    5
    Views:
    539
    Teemu Keiski
    Jul 18, 2004
  2. =?Utf-8?B?RGlmZmlkZW50?=

    Question on optimizing a piece of code

    =?Utf-8?B?RGlmZmlkZW50?=, Jun 9, 2005, in forum: ASP .Net
    Replies:
    3
    Views:
    402
    Patrice
    Jun 9, 2005
  3. Hristo Stevic

    highlight the piece of code executed

    Hristo Stevic, Dec 7, 2003, in forum: Java
    Replies:
    0
    Views:
    346
    Hristo Stevic
    Dec 7, 2003
  4. Moritz Beller
    Replies:
    19
    Views:
    692
    Pete Becker
    Jun 4, 2004
  5. Patrick Plattes

    Download a file piece by piece

    Patrick Plattes, Nov 30, 2006, in forum: Ruby
    Replies:
    2
    Views:
    222
    Patrick Plattes
    Nov 30, 2006
Loading...

Share This Page