After this lesson, you will be able to: Understand arrays in memory, strings as null-terminated char arrays, string.h functions, and why buffer overflows happen.
C arrays + strings are the source of half of CVEs in the wild. Understanding them prevents writing the next one.
Read carefully.
int main(void) {int nums[5] = {1, 2, 3, 4, 5};int n = sizeof(nums) / sizeof(nums[0]); // 5, array length idiomfor (int i = 0; i < n; i++) {printf("%d\n", nums[i]);}// CRUCIAL: arrays do NOT carry their length around when passed to functions.// void print(int arr[]), inside print, sizeof(arr) is the size of a POINTER.// Always pass length explicitly: void print(int *arr, size_t n).int matrix[2][3] = { {1,2,3}, {4,5,6} }; // 2D arrayreturn 0;}
Source of countless bugs.
#include <stdio.h>#include <string.h>int main(void) {char s1[] = "hello"; // 6 bytes: 'h','e','l','l','o','\0'char s2[10] = "hi"; // 10 bytes; 'h','i','\0', then 7 unused byteschar *s3 = "world"; // pointer to string literal (READ-ONLY)size_t len = strlen(s1); // 5, does NOT count the null terminatorchar copy[20];strncpy(copy, s1, sizeof(copy) - 1); // SAFE: bounded copycopy[sizeof(copy) - 1] = '\0'; // ensure null-termination// NEVER: strcpy(copy, src) without knowing src length// gets(buf), removed from standard for being unsafeif (strcmp(s1, "hello") == 0) printf("match\n");return 0;}
fgets > gets > scanf for line input.
char buf[256];// Reads up to sizeof(buf)-1 chars + null terminator; safe.if (fgets(buf, sizeof(buf), stdin) != NULL) {// strip trailing newlinebuf[strcspn(buf, "\n")] = '\0';printf("Hello, %s\n", buf);}// NEVER use gets(), removed from C11 for being unsafe.// scanf("%s", ...) without width specifier is also dangerous.
strcpy, strcat without bounds checking. Off-by-one on null terminator. Assuming sizeof(arr) inside a function gives array length (it gives pointer size). Forgetting that string literals are read-only, `char *p = "hi"; p[0] = 'H';` is undefined.
Pick the C-spec answer.
Sign in and purchase access to unlock this lesson.