Accessing C++ Memory like we do in Assembly
CS 301 Lecture, Dr. Lawlor
There's a common feature to this OpenGL function call:
void glVertexPointer( GLint size,
GLenum type,
GLsizei stride,
const GLvoid *ptr );
And the standard UNIX binary disk write function:
ssize_t write(int fd, const void *buf, size_t count);
And the standard BSD network socket communication function:
ssize_t send(int sockfd, const void *buf, size_t len, int flags);
They all:
- Take a "void *", a pointer to some unspecified object in memory.
- Want sizes or counts in bytes.
That is, they're all C++, but they treat memory like assembly treats memory.
Void Pointer
One standard trick when treating memory as bytes is a "void *". This
is a pointer to some type, but you're unwilling to tell the compiler
exactly what you're pointing to. "void *" is usually used as an
argument into some carefully-written function that will then move some
bytes around.
Memory as Bytes
If you think about memory as bytes, only two things matter: where is
the data, and how much is there. The class name doesn't
matter. The intended use of the data doesn't matter. All
you need is a pointer and a byte count, and you can copy the data to
disk, send it across the network, hand it to another processor,
etc.
For example, here we're writing into the middle of a char array using a "long *":
enum {n=32};
char data[n];
long *ptr=(long *)&data[0];
ptr++;
*ptr=-1;
/* Print bytes in "data" array. */
for (int i=n-1;i>=0;i--) {
const char *hexdigit="0123456789ABCDEF?";
std::cout<<hexdigit[(data[i]>>4)&0xf];
std::cout<<hexdigit[(data[i] )&0xf];
if ((char *)ptr==&data[i]) std::cout<<"<"; else std::cout<<" ";
}
std::cout<<"\n";
(Try this in NetRun now!)
Here we make the same change using an "int *":
int *ptr=(int *)&data[0];
ptr+=2;
*ptr=-1;
ptr++;
*ptr=-1;
(Try this in NetRun now!)
Here we use "memset", which takes... a pointer and a byte count.
int *ptr=(int *)&data[0];
memset(ptr+2,0xff,8);
(Try this in NetRun now!)