Swap example

Here we will briefly annotate the swap example discussed in lecture.

We have the following pseudocode of a function we want to write:

void swap(pointer to data1, pointer to data2) {
	store a copy of data1 in temporary storage
	copy data2 to location of data1
	copy data in temporary storage to location of data2
}

Let us translate each line.

  1. The first line is the function signature. We don't know the types of data1 and data2 so we need a pointer to "something" where we do not know the type of something. How do we do this? Via void *:
void swap(void *data1ptr, void *data2ptr) {
  1. Next we want to store a copy of data1 into some form of temporary storage. Of course, the problem is that we do not know the type of data1 so we do not know how many bytes to allocate in memory. Thus, we must take in another parameter in the function signature which denotes the size of the data in bytes. We now have
void swap(void *data1ptr, void *data2ptr, size_t nbytes) {

How can we make nbytes of temp space to copy data1 into? We need some sort of fundamental unit which we can perform arithmetic on to get the number of bytes we need. For that, we can use char arrays since each char is exactly one byte!

void swap(void *data1ptr, void *data2ptr, size_t nbytes) {
	char temp[nbytes];

But how do we physically go to the location of data1 and copy the correct amount of bytes into temp? Your first thought might be to try and deference the void pointer passed in. However you cannot do that. In fact, that is a very important rule of void pointers: you cannot deference a void *. This is because it does not know how many bytes it should return when you try to deference it since it is pointing to an unknown data type (the first element of the array if it is an array). Thus, we must manually tell C how many bytes to get and we have a function for this called memcpy. memcpy is a function that copies a specified amount of bytes at one address to another address. It copies the next nn bytes that src points to to the location contained in dest. (It also returns dest). We now have:

void swap(void *data1ptr, void *data2ptr, size_t nbytes) {
	char temp[nbytes];
	memcpy(temp, data1ptr, nbytes);
  1. We can now utilize this function to implement the rest:
void swap(void *data1ptr, void *data2ptr, size_t nbytes) {
	char temp[nbytes];
	// store a copy of data1 in temporary storage
	memcpy(temp, data1ptr, nbytes);
	// copy data2 to location of data1
	memcpy(data1ptr, data2ptr, nbytes);
	// copy data in temporary storage to location of data2
	memcpy(data2ptr, temp, nbytes);
}