Easier to read with cream paper, a tint, more contrast or larger text? Choose your colours and text, once, for every page.

Free lesson

C arrays and strings in memory

After this lesson: I can explain arrays as memory and strings as bytes that end in zero.

55 min lesson6 commandsCompilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

Why a C string ends in a zero

A string in C is an array of characters in memory that ends with a zero byte. That zero is the only mark of where the text stops. A missing zero, or too much text in too small an array, causes a famous family of bugs and security holes.

A form stores a name in eight bytes and works until somebody types nine letters.

By the end of this lesson

Note

I can explain arrays as memory and strings as bytes that end in zero.

Key words

WordWhat it meansExample
Arrayitems of one type stored side by sideint row[5]
Indexthe position of an item, counting from 0row[3]
Stringcharacters stored as bytes, ending in a zero byte
Terminatorthe zero byte that ends a string
Buffera block of memory set aside to hold data
Overflowwriting past the end of a buffer

The cells students fill in are left blank in this preview.

An array is items side by side

An array keeps items of one type next to each other in memory, with no gaps. Item row[3] is found by starting at the array and moving three items along. That is exactly *(row + 3).

C never checks an index. Ask for row[50] of a five-item array and it reads 50 items along, whatever is there.

Worked example: five ints from address 100

IndexAddressValue
01003
11041
21084
31121
41165

The cells students fill in are left blank in this preview.

An index and pointer arithmetic agree

Code: c
#include <stdio.h>

int main(void) {
  int row[5] = {3, 1, 4, 1, 5};
  printf("%d %d\n", row[3], *(row + 3));
  // Bytes in the whole array, then how many items that is.
  printf("array bytes %zu, items %zu\n", sizeof(row), sizeof(row) / sizeof(row[0]));
  return 0;
}

Write and build the array program

Command
printf '%s\n' '#include <stdio.h>' 'int main(void) {' '  int row[5] = {3, 1, 4, 1, 5};' '  printf("%d %d\n", row[3], *(row + 3));' '  printf("array bytes %zu, items %zu\n", sizeof(row), sizeof(row) / sizeof(row[0]));' '  return 0;' '}' | gcc -Wall -x c - -o arr

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Print one item two ways, and sizes

Command
./arr

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A string ends with a zero byte

C has no string type. A string is an array of char whose last byte is 0, the terminator. So "hello" takes six bytes: five letters and the zero.

strlen counts bytes until it meets a zero. sizeof gives the size of the whole array, zero included.

Worked example: the bytes of "hello"

IndexCharacterByte value
0h104
1e101
2l108
3l108
4o111
5The terminator0

The cells students fill in are left blank in this preview.

A zero in the middle ends the string

Code: c
#include <stdio.h>
#include <string.h>

int main(void) {
  char word[] = "hello";
  printf("sizeof %zu, strlen %zu\n", sizeof(word), strlen(word));
  word[2] = 0;  // put a zero where the first l was
  printf("now strlen %zu, text %s\n", strlen(word), word);
  return 0;
}

Write and build the string program

Command
printf '%s\n' '#include <stdio.h>' '#include <string.h>' 'int main(void) {' '  char word[] = "hello";' '  printf("sizeof %zu, strlen %zu\n", sizeof(word), strlen(word));' '  for (int i = 0; i <= 5; i++) printf("%d ", word[i]);' '  printf("\n");' '  word[2] = 0;' '  printf("now strlen %zu, text %s\n", strlen(word), word);' '  return 0;' '}' | gcc -Wall -x c - -o str

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Print sizes, codes and the cut string

Command
./str

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

A common mistake

Warning

Many people think a string stores its own length. It does not. C keeps the letters and one zero, and strlen walks to the zero every time. A text of five letters needs six bytes, so a buffer sized for exactly five is already too small.

Too much text overflows the buffer

A buffer is memory set aside for data, such as eight bytes for a name. If a program copies in nine letters and a zero, the extra bytes land on whatever is next. C does not stop it. The result is a crash, corrupted data or a security hole.

The model below copies with no length check, as strcpy does. It shows a neighbouring score being overwritten.

Watch a neighbour get overwritten

Code: python
# Memory: eight bytes for a name, then a score of 50 right after it.
memory = [0] * 8 + [50]
text = "Ana Patel"          # nine letters, one too many
# A copy with no length check, as strcpy does it.
for i in range(len(text)):
    memory[i] = ord(text[i])
print("score is now", memory[8])
# Change text to "Ana Pat" and run again.

Check the length before you copy

The fix is to know the size of the buffer and never copy more. snprintf takes the size and stops: it keeps what fits and always ends the string with a zero.

The next Run passes nine letters to a program with an eight byte buffer. Seven letters survive, and the eighth byte holds the zero.

Write and build a safe copy

Command
printf '%s\n' '#include <stdio.h>' '#include <string.h>' 'int main(int argc, char **argv) {' '  if (argc < 2) return 1;' '  char *text = argv[1];' '  char buf[8];' '  snprintf(buf, sizeof buf, "%s", text);' '  printf("%s has %zu letters, text has %zu\n", buf, strlen(buf), strlen(text));' '  return 0;' '}' | gcc -x c - -o safe

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

Print the cut name and both lengths

Command
./safe "Ana Patel"

Shown here, not run. Create a free account to press Run and type it into your own lab’s terminal.

About this lab and its source: Compilers and computer architecture lab: gcc, flex, bison and RISC-V in one VM

Teaching a class? Set this module for your students with a teacher guide, marked assignments and a lab for every student.