// A simple example of strings in C
// Illustrates:
// All kinds of mischief
// strings are allocated sequentially
// array indices are NOT checked
// can access memory outside of an array
// opens the door for all kinds of errors
//
// Compile: gcc errorstrings.c
// Run: a.out
// Optional Compile: gcc -o errorstrings errorstrings.c
// Optional Run: errorstrings
#include <stdio.h>
int main()
{
// Local variables are allocated from high to low addresses
int i;
int ohno;
char aStr2[] = "EFG"; // Notice: No 'D'
char aStr1[] = "ABC";
printf("String variable aStr1: '%s'\n", aStr1);
printf("String variable aStr2: '%s'\n", aStr2);
// Print EIGHT characters
for (i=0; i < 8; i++)
{
printf("Character %d, decimal, hex, and character: %d, %x, '%c'\n",
i, aStr1[i], aStr1[i], aStr1[i]);
}
printf("\n"); // Print a blank line
aStr1[3] = 'D'; // No array bounds checking! Yikes!
printf("aStr1 as string: '%s'\n", aStr1); // aStr1 as string: 'ABCDEFG'
printf("aStr2 as string: '%s'\n", aStr2); // aStr2 as string: 'EFG'
printf("\n");
for (i=0; i < 8; i++)
{
printf("Character %d, decimal, hex, and character: %d, %x, '%c'\n",
i, aStr1[i], aStr1[i], aStr1[i]);
}
printf("\n");
// No type checking and no array bounds checks!
aStr1[5] = 76; // What characters have values 75 and 76?
aStr2[-3] = 75; // Where do these values go?
printf("String variable aStr1: '%s'\n", aStr1);
printf("String variable aStr2: '%s'\n", aStr2);
printf("\n");
ohno = 0;
printf("Ohno before: %d\n", ohno);
aStr2[4] = 1; // Ouch!
printf("Ohno after: %d, %c\n", ohno, ohno);
aStr2[4] = 'a'; // Ouch!
printf("Ohno after: %d, %c\n", ohno, ohno);
// For strings, printf expects addresses, and so we must pass ohno's address
printf("Ohno after: %d, %c, %s\n", ohno, ohno, &ohno);
// Access values above aStr1 on the stack
printf("astr[-1]: %d, %c\n", aStr1[-1], aStr1[-1]);
aStr1[-1] = 'a'; // Ouch!
printf("astr[-1]: %d, %c\n", aStr1[-1], aStr1[-1]);
}
/* Output (when run on rucs):
String variable aStr1: 'ABC'
String variable aStr2: 'EFG'
Character 0, decimal, hex, and character: 65, 41, 'A'
Character 1, decimal, hex, and character: 66, 42, 'B'
Character 2, decimal, hex, and character: 67, 43, 'C'
Character 3, decimal, hex, and character: 0, 0, '^@'
Character 4, decimal, hex, and character: 69, 45, 'E'
Character 5, decimal, hex, and character: 70, 46, 'F'
Character 6, decimal, hex, and character: 71, 47, 'G'
Character 7, decimal, hex, and character: 0, 0, '^@'
aStr1 as string: 'ABCDEFG'
aStr2 as string: 'EFG'
Character 0, decimal, hex, and character: 65, 41, 'A'
Character 1, decimal, hex, and character: 66, 42, 'B'
Character 2, decimal, hex, and character: 67, 43, 'C'
Character 3, decimal, hex, and character: 68, 44, 'D'
Character 4, decimal, hex, and character: 69, 45, 'E'
Character 5, decimal, hex, and character: 70, 46, 'F'
Character 6, decimal, hex, and character: 71, 47, 'G'
Character 7, decimal, hex, and character: 0, 0, '^@'
String variable aStr1: 'AKCDELG'
String variable aStr2: 'ELG'
Ohno before: 0
Ohno after: 1, ^A
Ohno after: 97, a
Ohno after: 97, a, a
astr[-1]: 0, ^@
astr[-1]: 97, a
*/