Intermediate · Dynamic memory · topic 30 of 60 · 25 min
Dynamic strings and 2D arrays
Explanation
Copying a string to the heap
char *copy_string(const char *src) {
size_t len = strlen(src);
char *dst = malloc(len + 1); /* + 1 for '\0' */
if (!dst) return NULL;
memcpy(dst, src, len + 1);
return dst; /* the caller must free it */
}
char *name = copy_string("Meenakshi"); /* or: char *name = strdup("Meenakshi"); */
free(name);Building a string of unknown length
char *make_greeting(const char *name, const char *city) {
int needed = snprintf(NULL, 0, "Namaste %s from %s!", name, city); /* measure only */
if (needed < 0) return NULL;
char *s = malloc((size_t) needed + 1);
if (!s) return NULL;
snprintf(s, (size_t) needed + 1, "Namaste %s from %s!", name, city);
return s;
}2D arrays: an array of row pointers
int rows = 3, cols = 4;
int **grid = malloc(rows * sizeof *grid); /* an array of row pointers */
for (int r = 0; r < rows; r++) {
grid[r] = calloc(cols, sizeof *grid[r]); /* each row separately */
}
grid[1][2] = 7;
/* free in reverse order: rows first, then the row array */
for (int r = 0; r < rows; r++) free(grid[r]);
free(grid);
grid ──► [ row0 ptr ] ──► | 0 | 0 | 0 | 0 |
[ row1 ptr ] ──► | 0 | 0 | 7 | 0 |
[ row2 ptr ] ──► | 0 | 0 | 0 | 0 |2D arrays: one contiguous block
int *cells = calloc((size_t) rows * cols, sizeof *cells);
cells[1 * cols + 2] = 7; /* row 1, column 2 */
free(cells); /* one free */| Array of row pointers | One contiguous block | |
|---|---|---|
| Indexing | grid[r][c] | cells[r * cols + c] |
| Allocations | rows + 1 | 1 |
| Freeing | Each row, then the array | One free |
| Jagged rows | Possible | No |
| Speed | Rows may be scattered in memory | Cache-friendly |
Arrays of strings
char **names = malloc(count * sizeof *names);
for (int i = 0; i < count; i++) names[i] = strdup(input[i]); /* each name its own block */
/* … */
for (int i = 0; i < count; i++) free(names[i]);
free(names);Need help?
Stuck on a word or an idea? Search this course, or every course, and jump straight to the explanation or a worked question.
Try:
Watch the lesson
Dynamic strings and 2D arrays · 1/6
In this lesson you will allocate strings and tables at run time.
Prefer a video by a teacher? Find free videos on “c dynamic 2d array malloc array of strings strdup” on YouTube ↗
In real life: A seating chart sized at run time
An exam-hall allocation tool reads the number of rows and benches per row for each hall from a file, then allocates a contiguous grid of roll numbers. One allocation per hall keeps freeing simple and printing fast.
int *seats = calloc((size_t) rows * benches, sizeof *seats);
if (!seats) return 1;
int roll = 1001;
for (int r = 0; r < rows; r++)
for (int b = 0; b < benches; b++)
seats[r * benches + b] = roll++;
/* print, then */
free(seats);Practice (0/3 done)
Which allocation correctly holds a copy of the string s?
A grid was made with grid = malloc(rows * sizeof *grid) and a malloc per row. What is the correct way to free it?
Write char *join_names(const char **names, int n) that returns one heap string with all names separated by ", " (measure the total length first, allocate once, then build it). Also write a matrix allocator int *matrix_new(int rows, int cols) using one calloc, and a function to print it. Free everything and check with a leak checker.
Quick quiz
Read more (free)
Related help
Before this, learn
This topic builds on these. If something here feels new, open them first.
Related topics
- realloc and growing arraysDynamic memory · same module
- malloc, calloc and freeDynamic memory · same module
- Arrays: one name, many valuesC# and .NET · Arrays, strings and null
- Arrays, std::array and a first look at std::vectorC++ Programming (modern C++ and DSA) · References, pointers, arrays and strings
- Two-dimensional arrays and array algorithmsJava Programming (Core to Spring Boot) · Arrays and strings
- Pointers and arraysPointers
Questions people ask about this
Open a question to see the answer and why. The first ones are this topic's own quiz, so try the quiz above before you peek.
What does strdup do?
Answer: Allocates a copy of a string on the heap
The caller must free the result.
In a contiguous rows × cols block, where is element (r, c)?
Answer: cells[r * cols + c]
Row-major indexing.
How many frees does an array of 5 row pointers (each row malloc'd) need?
Answer: 6
5 rows + the pointer array.
What does snprintf(NULL, 0, "%d", 12345) return?
Answer: 5
The number of characters the text would need (without the terminator).
What is the index of the last item in an array of length 8?Related
In a function parameter for a 2D int array with 4 columns, which is valid?Related
Answer: int g[][4]
All dimensions except the first are required.
What is the index of the LAST element of an array of size 10?Related
In int[][] t = new int[3][5]; what is t.length and t[0].length?Related
Answer: 3 and 5
First dimension rows (3), second columns (5).
Pass the quiz (60% or more) or mark this topic as done when you are ready.
Your progress is saved on this device only.
Next steps
- This is the last topic of “Dynamic memory”. The module exam comes next.
- Module 6 exam: Dynamic memory · 12 questions · 25 min, without help. 5 topics of this module still to finish first.
- Then the next module, Structs, unions, enums and files. 60 topics left in the course before the final exam.