█
LastWrite
  • > Curriculum
  • > Pricing
  • > For Educators
  • > About
  • > Contact
Log InGet Started

Questions, concerns, bug reports, or suggestions? We read every message, write to us at [email protected].

More ways to reach us →
LastWrite

Structured computer science lessons for aspiring developers and security professionals.

[email protected]

(201) 785-7951

Mon–Fri, 9 AM–5 PM EST

Learn

  • Curriculum
  • Pricing

Company

  • About
  • For Educators & Schools
  • Contact Us

Legal

  • Terms of Service
  • Privacy Policy
© 2026 LastWrite. All rights reserved.
Curriculum/Programming Languages/C/Arrays and Strings
50 minIntermediate

Arrays and Strings

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.

Prerequisites:C Fundamentals

Arrays — contiguous memory

Read carefully.

tsx
int main(void) {
int nums[5] = {1, 2, 3, 4, 5};
int n = sizeof(nums) / sizeof(nums[0]); // 5, array length idiom
for (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 array
return 0;
}

Strings — null-terminated char arrays

Source of countless bugs.

tsx
#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 bytes
char *s3 = "world"; // pointer to string literal (READ-ONLY)
size_t len = strlen(s1); // 5, does NOT count the null terminator
char copy[20];
strncpy(copy, s1, sizeof(copy) - 1); // SAFE: bounded copy
copy[sizeof(copy) - 1] = '\0'; // ensure null-termination
// NEVER: strcpy(copy, src) without knowing src length
// gets(buf), removed from standard for being unsafe
if (strcmp(s1, "hello") == 0) printf("match\n");
return 0;
}

💡 Why buffer overflows happen

C arrays don't bounds-check. `arr[1000]` on a 10-element array = undefined behavior, often a crash or arbitrary memory write. When attackers control the index or the data written, they can overwrite return addresses (classic stack smashing) and execute arbitrary code. Defense: ALWAYS check bounds; use strncpy/snprintf with explicit lengths; use modern alternatives (snprintf > sprintf, strlcpy > strcpy on systems that have it).

Safe input reading

fgets > gets > scanf for line input.

tsx
char buf[256];
// Reads up to sizeof(buf)-1 chars + null terminator; safe.
if (fgets(buf, sizeof(buf), stdin) != NULL) {
// strip trailing newline
buf[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.

Common mistakes only experienced C devs avoid

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.

Quick Check

Why is `char *p = "hi"; p[0] = 'H';` undefined behavior?

Pick the C-spec answer.

Sign in and purchase access to unlock this lesson.

Sign in to purchase
←C Fundamentals
Back to C
Pointers→