// 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 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,  Ohno after: 97, a Ohno after: 97, a, a astr[-1]: 0, astr[-1]: 97, a */