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:
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!)