Solved

Pointer aritmetics?

Posted on 2006-07-18
9
304 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
ID: 17129264
>>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
ID: 17129274
>>++ptr;

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

Expert Comment

by:Axter
ID: 17129286
FYI:

I recommend not using void, and instead use the correct type.
I also recommend not using malloc, and instead use new
0
ScreenConnect 6.0 Free Trial

Explore all the enhancements in one game-changing release, ScreenConnect 6.0, based on partner feedback. New features include a redesigned UI, app configurations and chat acknowledgement to improve customer engagement!

 
LVL 30

Expert Comment

by:Axter
ID: 17129301
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
 
LVL 53

Expert Comment

by:Infinity08
ID: 17129308
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
ID: 17129313
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
ID: 17129449
>> [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
ID: 17129450
>> 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
ID: 17129603
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

DevOps Toolchain Recommendations

Read this Gartner Research Note and discover how your IT organization can automate and optimize DevOps processes using a toolchain architecture.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

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…
Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
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 be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

821 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