Solved

Pointer aritmetics?

Posted on 2006-07-18
9
283 Views
Last Modified: 2008-01-09
Hi!

This is a question about pointer aritmetics.
I have allocated a buffer with the size of 6400.

void* HeaderBuffer = malloc(6400);
....
.
iStream.read(static_cast<char*>(HeaderBuffer),6400);
....
..

And then then i have a pointer that should point to struct

Header* header_ptr = static_cast<Header*>(HeaderBuffer);

then i have a loop so that i can go through the buffer byte for byte

int ptr;

while(header_ptr->STX != 0x0002) {
        header_ptr = static_cast<Header*>(HeaderBuffer) + ptr;
        ++ptr;
        int size = (char*) header_ptr - (char*)HeaderBuffer;
}

the int size is just for me to se how much the address is increaset and i noticed that even though the ptr is only incremented by one for each loop the header_ptr is incremented by 48 which is the sixe of the struct. I would like the header_ptr to be incremented by on byte.

I would prefer to keep the header_ptr to be a Header* pointer since then i can use the struct to check the values,
the values vary from 16 to 32 bit.

Thanks for the help


0
Comment
Question by:mikrodidakt
  • 4
  • 2
  • 2
  • +1
9 Comments
 
LVL 30

Accepted Solution

by:
Axter earned 150 total points
Comment Utility
>>I would like the header_ptr to be incremented by on byte.

If you want to increment it by one, then you need to cast it to a one byte type before incrementing it.
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
>>++ptr;

Instead of the above, do the following:
ptr =  (Header*) ( ( (char*) ptr) + 1);
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
FYI:

I recommend not using void, and instead use the correct type.
I also recommend not using malloc, and instead use new
0
 
LVL 30

Expert Comment

by:Axter
Comment Utility
I just notice ptr is not a pointer, and instead is an integer.
The code I posted would be appropriate if ptr was a pointer of type Header.

In any case, if you want to increment a struct pointer by single byte, you still need to cast it to a single byte type, as in the example I posted.
0
How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

 
LVL 53

Expert Comment

by:Infinity08
Comment Utility
btw, this :

        header_ptr = static_cast<Header*>(HeaderBuffer) + ptr;
        ++ptr;

is the same as :

        ++header_ptr;

No need to make things more complicated than they are :)

For the answer to your question, ignore this post and check Axter's posts.
0
 

Author Comment

by:mikrodidakt
Comment Utility
char* tmp_ptr = static_cast<char*>(HeaderBuffer) + ptr;
header_ptr = static_cast<Header*>(tmp_ptr);

[C++ Error] filehandler.cpp(35): E2031 Cannot cast from 'char *' to 'Header *'????

But if use the c standard

header_ptr = (Header*) tmp_ptr;

I get it to work, why? Should I leave it or is there a way to use the C++ standard?

0
 
LVL 53

Assisted Solution

by:Infinity08
Infinity08 earned 100 total points
Comment Utility
>> [C++ Error] filehandler.cpp(35): E2031 Cannot cast from 'char *' to 'Header *'????
char* and Header* are not compatible types, so you'll need a reinterpret_cast or a C-style cast.


Either do this : (if it's just the first byte you need to check - if it's a different byte, there's only minor modifications to do)

    unsigned char *HeaderBuffer = malloc(6400);
    iStream.read(HeaderBuffer, 6400);
    unsigned char *ptr = HeaderBuffer;
    while (*ptr != 0x02) {
      ++ptr;
    }
    Header* header_ptr = (Header*) ptr;

or :

    Header *HeaderBuffer = malloc(6400);
    iStream.read((char*) HeaderBuffer, 6400);
    Header* header_ptr = HeaderBuffer;
    while (header_ptr->STX != 0x0002) {
      header_ptr = (Header*) (((char*) header_ptr) + 1);
    }

The last is what Axter suggested !! So, don't give me any points for this !!
0
 
LVL 7

Expert Comment

by:nafis_devlpr
Comment Utility
>> I would like the header_ptr to be incremented by on byte.

>>I would prefer to keep the header_ptr to be a Header* pointer since then i can use the struct to check the values,
the values vary from 16 to 32 bit.

This two lines are contardictory, cause if you want the header pointer by one byte keeping it as Header* you will certainly not get the appropiate or correct value for the field you are going to use as the pointer increament by one byte and will load data after that byte which will definitly give you improper values in their fields.

let me give you a simple example to clarify:

struct TEMP
            {
                  char a,b,c;
            }ttr[10];

//somewhere in the code you initialize the buffer
char a='a';

for(int i=0; i < 10; i++)
      {
            ttr[i].a=a++;
            ttr[i].b=a++;
            ttr[i].c=a++;
      }

TEMP* st=ttr;
for(i=0; i < 10; i++)
      {
                 printf("%c %c %c\n",st->a,st->b,st->c);
            st=(TEMP*)(((char*)st)+1);
      }

just see the values it prints. cause its not what you are expecting

even if u still want to traverse the struct by one byte you can do the following

header_ptr=(Header*)(((char*)header_ptr)+1);

this will increament header_ptr by one byte

Hope this helps

Nafis
0
 

Author Comment

by:mikrodidakt
Comment Utility
Hi nafis_devlpr thanks for the answer.
 
This is the struct that i am using
typedef struct{
        //--------HEADERS-------
        unsigned __int16 STX;
      unsigned __int16 CRC;
        unsigned __int16 MachID;
        unsigned __int16 ClinicalSWID;
        unsigned __int32 MsgCounter;
        unsigned __int32 CmdCode;
        unsigned __int32 MsgInfo;
        unsigned __int32 Flags;
        unsigned __int32 PatId1;
        unsigned __int32 PatId2;
        unsigned __int32 PatId3;
        unsigned __int32 SWRevision;
        unsigned __int32 Time;
        unsigned __int32 MBL;
        //----------------------
}Header;

when i find the 0x0002 i have to check the rest of the variabels.

iStream.read(static_cast<char*>(HeaderBuffer),6400);
Header* header_ptr = static_cast<Header*>(HeaderBuffer);
int ptr = 1;
while(header_ptr->STX != 0x0002 && ptr <= 6400) {
         char* tmp_ptr = static_cast<char*>(HeaderBuffer) + ptr;
         header_ptr = (Header*) tmp_ptr;
         ++ptr;
}
...
.....
memcpy(HeaderBuffer, header_ptr, static_cast<unsigned int>(32000-ptr));
header = static_cast<Header*>(HeaderBuffer);
..
....
//Checking the other variabels..
...
.

So I think I got it. But i will change it in the while loop to what Infinity08 has writen.
Thanks.


0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

In days of old, returning something by value from a function in C++ was necessarily avoided because it would, invariably, involve one or even two copies of the object being created and potentially costly calls to a copy-constructor and destructor. A…
Basic understanding on "OO- Object Orientation" is needed for designing a logical solution to solve a problem. Basic OOAD is a prerequisite for a coder to ensure that they follow the basic design of OO. This would help developers to understand the b…
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

763 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now