Duplicate a String

Now that we learned about memory allocation, we'll look at the first application of it, which is allocating a memory for a copy of an existing string. We'll need to do it quite often during the course, so now it's a good time to learn how to do it.

strdup function

Unlike other string functions we talked about earlier, strdup is not a part of any “official” C standard, but it exists in most real life C implementations. This function accepts a string and then does the following:

  1. Calculates the length of that string using strlen;
  2. Allocates memory for the copy of that string using malloc. Remember to allocate an extra character for the terminating zero character!
  3. Copies the source string to the allocated memory using strcpy;
  4. Returns the pointer to the allocated memory.

Here is how we normally use it:

char s[] = "test string";
char *p;

p = strdup(s); /* p points to a newly allocated memory */

/* use p: */
printf("p: %s\n", p);

/* free the memory when you don't need p anymore */
free(p);

Why would you need to duplicate a string this way? The main use case is when your program need to store many strings–maybe, an array of strings–and you cannot preallocate memory for all those strings because you don't know how large they will be. In that case you might read those strings from the input into an array, like s in the example above, and remember their duplicates, allocating as much memory as needed for each of the strings.

If you don't feel this explanation makes sense, on the next few pages I will show some examples of this technique. But before we go there, let's implement our own strdup to understand that it indeed works as I described.

The test code for this exercise will read a string from the standard input, call strdup and then modify the original string. The copy must stay intact.

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

char *mystrdup(char *s) {
	/* TODO: implement this function:
     get a length of s, allocate memory for the length and one more character,
     copy the content and return */

	return NULL;
}

int main() {
	char s[100];
	char *p;

	fgets(s, 100, stdin);

	/* duplicate it: */
	p = mystrdup(s);

	/* change s */
	strcpy(s, "some new content");

	/* p still has the original string */
	printf("p: %s\n", p);

	/* free memory */
	free(p);

	return 0;	
}

On the next few pages we'll use strdup to solve a classic exercise: count number of occurrences of each word in a text. Stay tuned!

© Alexander Fenster (contact)