Question
What is the purpose of the strdup() function in C, and how should its returned string be managed?
Short Answer
strdup() creates an independent, dynamically allocated copy of a null-terminated C string. You will learn how it works, why free() is required, and how to handle errors safely.
Concept
strdup() means string duplicate. It accepts a pointer to a null-terminated character string and returns a pointer to a newly allocated copy of that string.
char *copy = strdup("hello");
After this call, copy points to memory containing its own characters: "hello\0". It is separate from the original string, so modifying the copy does not modify the original.
Conceptually, strdup() performs these steps:
- Finds the length of the source string, excluding its terminating
\0character. - Allocates enough heap memory for all characters plus one for
\0. - Copies the source string into that memory.
- Returns the address of the new memory.
The allocated memory belongs to the caller. When it is no longer needed, release it with free().
char *name = strdup("Ada");
if (name != NULL) {
printf("%s\n", name);
free(name);
}
strdup() is specified by POSIX, not by the ISO C standard. It is widely available on Unix-like systems. In strictly portable ISO C programs, write an equivalent helper using malloc() and memcpy() or strcpy().
Mental Model
Think of a string as text written on a sheet of paper.
- A pointer to a string is like being given the address of the original sheet.
strdup()is like photocopying that sheet and giving you the new copy.- You may write on your copy without changing the original.
- Because the photocopy uses new storage, you are responsible for throwing it away later with
free().
Simply assigning a pointer does not make a copy:
char *a = "hello";
char *b = a; // Both pointers refer to the same string.
Using strdup() does:
char *a = "hello";
char *b = strdup(a); // b refers to separately allocated memory.
Syntax and Examples
The basic syntax is:
char *strdup(const char *source);
sourceis a valid null-terminated string.- The result is a newly allocated duplicate, or
NULLwhen allocation fails. - The caller must eventually call
free()on a successful result.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(void) {
const char *original = "coffee";
char *copy = strdup(original);
if (copy == NULL) {
fprintf(stderr, "Could not allocate memory\n");
return 1;
}
copy[0] = 'C';
printf("original: %s\n", original);
(, copy);
(copy);
;
}
Step by Step Execution
Consider this program fragment:
const char *label = "draft";
char *saved_label = strdup(label);
if (saved_label == NULL) {
return 1;
}
saved_label[0] = 'D';
printf("%s / %s\n", label, saved_label);
free(saved_label);
Step by step:
labelpoints to the string literal"draft".strdup(label)measures the source string. Its length is 5.- It allocates 6 bytes: five letters and one terminating
\0. - It copies
d,r,a,f,t, and\0into the new allocation. saved_labelreceives the pointer to that allocation.- The
NULLcheck ensures the program does not use memory if allocation failed.
Real World Use Cases
strdup() is useful whenever a program must keep its own copy of text instead of borrowing someone else's pointer.
- Configuration parsing: Copy a value such as
"production"from a temporary input buffer before the buffer is reused. - Command-line tools: Save command-line arguments in a data structure that outlives the parsing step.
- HTTP or API processing: Duplicate a request header or JSON-derived text before destroying the request buffer.
- Data structures: Store independently owned names in a linked list, hash table, or record.
- Environment data: Copy a value returned by
getenv()if it must remain stable after environment-related operations. - Text transformations: Duplicate input text before editing it in place with functions such as
strtok()or direct character changes.
For example, a contact record can own its name:
struct Contact {
char *name;
};
struct Contact contact = {0};
contact.name = strdup("Lin");
/* Use contact.name... */
free(contact.name);
Real Codebase Usage
In real projects, strdup() is usually paired with clear ownership rules: the code that duplicates a string owns the result and must free it, or it transfers that responsibility to another object.
Validate allocation immediately
char *path_copy = strdup(path);
if (path_copy == NULL) {
return -1;
}
This is a guard clause. It prevents a later null-pointer dereference.
Clean up on later failure
char *host_copy = strdup(host);
if (host_copy == NULL) {
return -1;
}
char *port_copy = strdup(port);
if (port_copy == NULL) {
free(host_copy);
return -1;
}
/* Use both copies. */
free(port_copy);
free(host_copy);
Transfer ownership into a structure
struct User {
char *username;
};
int user_set_name( User *user, *name) {
*new_name = strdup(name);
(new_name == ) {
;
}
(user->username);
user->username = new_name;
;
}
Common Mistakes
Forgetting to free the result
This leaks memory when repeated:
char *copy = strdup(input);
/* copy is never freed */
Fix it by freeing the pointer after its final use:
free(copy);
Ignoring allocation failure
strdup() can return NULL if memory cannot be allocated.
char *copy = strdup(input);
printf("%s\n", copy); // Unsafe if copy is NULL.
Check first:
char *copy = strdup(input);
if (copy == NULL) {
return 1;
}
Modifying a string literal instead of the duplicate
This has undefined behavior:
char *text = "hello";
text[0] = 'H';
Make a writable copy:
Comparisons
| Approach | Creates separate character storage? | Can modify result? | Must call free()? |
|---|---|---|---|
char *b = a; | No | Depends on what a points to | No new allocation |
strdup(a) | Yes | Yes, if successful | Yes |
char buffer[50]; strcpy(buffer, a); | Yes | Yes | No, but buffer has fixed capacity |
malloc(strlen(a) + 1) then copy | Yes | Yes | Yes |
Pointer assignment versus duplication
Cheat Sheet
#include <stdlib.h>
#include <string.h>
char *copy = strdup(source);
if (copy == NULL) {
/* Handle allocation failure. */
}
/* Use or modify copy. */
free(copy);
strdup()duplicates a null-terminated string.- Return type:
char *. - Success: pointer to newly allocated writable memory.
- Failure:
NULL. - Allocation: heap memory.
- Cleanup: call
free()exactly once for each successful duplication. - Do not pass
NULLas the source. - Do not use the result after
free(). strdup()is POSIX, not ISO C.- The duplicate includes the terminating
\0character. - Pointer assignment copies only the pointer;
strdup()copies the characters.
FAQ
What does strdup() return in C?
It returns a pointer to a newly allocated copy of the source string. If allocation fails, it returns NULL.
Does strdup() allocate memory?
Yes. It allocates heap memory large enough for the characters in the source string and its terminating null character.
Do I need to free a string returned by strdup()?
Yes. Call free() once when the duplicate is no longer needed.
Is strdup() part of standard C?
No. It is part of POSIX and is commonly available on Unix-like systems. Strictly portable C code can implement the same behavior with malloc() and a copy operation.
Can I modify the result of strdup()?
Yes, if it did not return NULL. The returned allocation is writable.
Does changing a strdup() result change the original string?
No. The duplicate has separate storage, so changes affect only the copy.
What happens if I call strdup(NULL)?
The behavior is undefined. Ensure the source pointer refers to a valid null-terminated string first.
Mini Project
Description
Create a small program that stores a user-entered label safely. The input buffer can be reused or changed, but the saved label must remain an independent copy. This demonstrates why programs duplicate strings before keeping them in longer-lived data structures.
Goal
Read one label, duplicate it with strdup(), convert the saved copy to uppercase, print it, and release its memory.
Requirements
Read a label of up to 99 characters using fgets().
Remove the trailing newline if one was read.
Use strdup() to create a dynamically allocated copy of the label.
Check whether duplication succeeded before using the copy.
Convert only the duplicate to uppercase and print it.
Free the duplicated string before the program exits.
Keep learning
Related questions
2D Array Loop Order and Cache Performance in C
Learn why swapping nested loops changes 2D array performance in C, using row-major memory layout, cache locality, and practical benchmarks.
Array-to-Pointer Conversion in C and C++ Explained
Learn what array-to-pointer conversion means in C and C++, how array decay works, and how it differs from a pointer to an array.
Building More Fault-Tolerant Embedded C++ Applications for Radiation-Prone ARM Systems
Learn practical C++ and compile-time techniques to reduce soft-error damage in embedded ARM systems exposed to radiation.