Page 1 of 1

Blobs of Data and Pointers

Posted: Mon Jan 28, 2013 5:40 am
by Crayon Shin Chan
I've to extend someone's program, where I found him loading a bitmap into memory, and storing the pointer (a char*) to the first byte of this blob and the length somewhere. Is this common practice?

It seemed to be sensible behaviour until I noticed that *pointertoblob was just pointertoblob[0], makes sense, since char* is only one byte, and thus it only points to one byte.

But cout << pointertoblob doesn't give me an address like it normally would, instead it gives me the whole blob. And it didn't even need to know how long the blob was. How is this possible? How can I make a blob somewhere in memory which I can play around with in my own test program? What is the name of this technique so I can search it?

Re: Blobs of Data and Pointers

Posted: Mon Jan 28, 2013 8:19 am
by SecretSquirrel
Yes it's common. It is generally how one loads a "blob" of binary data into a buffer in memory. The insertion oiperation knows that when it recieves a char * input, it is to insert the string of characters pointed at into the output stream. You probably aren't getting the whole blob, though it is possible. You will get up to the first 0 byte that would normally terminate a string. I'll ignore the fact that << could be overloaded to do something else.

I suspect that if you "cout << (void *)pointertoblob;", you will get the address you are expecting.

char *myblob;
myblob=new char[1024];


The above allocates 1024 bytes of type char and store the pointer to them in myblob.

Enjoy your new found world of pointers and memory. BTW, make sure to look up "delete".

--SS

Re: Blobs of Data and Pointers

Posted: Mon Jan 28, 2013 8:38 am
by Flying Fox
Crayon Shin Chan wrote:
I've to extend someone's program, where I found him loading a bitmap into memory, and storing the pointer (a char*) to the first byte of this blob and the length somewhere. Is this common practice?
Very common, with another variation using "array" of unsigned char instead, since you can deal with values of 0-255 instead of (-127)-128 when you manipulate the data.

Crayon Shin Chan wrote:
It seemed to be sensible behaviour until I noticed that *pointertoblob was just pointertoblob[0], makes sense, since char* is only one byte, and thus it only points to one byte.
Since your pointer is defined as char*, of course when you dereference it is going to be one byte (if you use a pointer of different type, you will see different results). This is just basic pointer arithmetic. However, when you advance the pointer, you will be pointing to the other bytes in the blob. Example:
unsigned char *p = new unsigned char[100];
// put some data in that blob of memory
// ...

// initially, the pointer points to the first byte of the array
cout << "They are equal: " << (*p == p[0]) << endl;

// let's play some pointer arithmetic
cout << "Also equal: " << (*(p + 2) == p[2]) << endl;

// use a different pointer and then traverse the array
unsigned char *q = p;  // not assigning value of the byte, just the address
for (int i = 0; i < 100; ++i) {
  cout << "Byte #" << i + 1 << ": " << (int)(*q);  // char values may be unprintable, display int values instead
  ++q;
}

// assume no alignment issue, I can play this really dangerous game of type casting
int *r = (int *)p;  // pointing to the same address, assuming 32-bit integers
cout << "First 4-byte integer: " << *r << endl;
cout << "Second 4-byte integer: " << *(++r) << endl;  // your pointer address moves by 4 each time now

// this is bad, since you lose the original reference to the blob!!
++p;


Crayon Shin Chan wrote:
But cout << pointertoblob doesn't give me an address like it normally would, instead it gives me the whole blob. And it didn't even need to know how long the blob was. How is this possible? How can I make a blob somewhere in memory which I can play around with in my own test program? What is the name of this technique so I can search it?
Two things:
1. Since pointertoblob is defined as (char *), there is a specific overload of iostream::operator<<() with char* and assumes that this is a null-terminated string.
2. Since it assumes a null-terminated string, printing will continue until it hits a null character. It is not a matter of knowning how long the blob was. If your blob has a 0 value somewhere before the end of the array, you will get a shorter string. OTOH, if your array has no element with a value of 0, it will continue to print beyond the size of your array until it hits a 0 value memory cell. This will be a case of buffer overrun and usually you will trample on some memory that you are not supposed to touch and get an access violation.

If you just want to print the address, just C-cast the pointer to an integer value.
cout << "Address of pointer is: 0x" << hex << (unsigned int)pointertoblob << endl;  // assume 32-bit pointers

Re: Blobs of Data and Pointers

Posted: Mon Jan 28, 2013 10:23 am
by just brew it!
Whoever thought it was a good idea to overload the << and >> operators to perform I/O should be shot. "Oooh, look, we have this cool operator overloading feature! Let's use it to make operators do something unintuitive and completely unrelated to their original function!" And then (since the concept is ill-conceived to begin with) they need to introduce the concept of manipulators (and hidden state in the stream object) to control formatting. Brain damage on top of brain damage! :roll:

Sorry for the slightly off-topic rant... in case you can't tell, I'm not a fan of the standard C++ stream I/O library. :lol:

Re: Blobs of Data and Pointers

Posted: Mon Jan 28, 2013 11:36 am
by Crayon Shin Chan
You guys have been a great help :D

Re: Blobs of Data and Pointers

Posted: Mon Jan 28, 2013 12:33 pm
by Flying Fox
just brew it! wrote:
Whoever thought it was a good idea to overload the << and >> operators to perform I/O should be shot. "Oooh, look, we have this cool operator overloading feature! Let's use it to make operators do something unintuitive and completely unrelated to their original function!" And then (since the concept is ill-conceived to begin with) they need to introduce the concept of manipulators (and hidden state in the stream object) to control formatting. Brain damage on top of brain damage! :roll:

Sorry for the slightly off-topic rant... in case you can't tell, I'm not a fan of the standard C++ stream I/O library. :lol:

I actually think the overloads save me the trouble of remembering when to use d, s, l, etc. for types. Manipulators and format specifiers are a wash though, have to remember them anyways.