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
The Model M is not for the faint of heart. You either like them or hate them.
Gerbils unite! Fold for UnitedGerbilNation, team 2630.