C characters, strings and buffer capacity
Objectives and contracts
Extend the array/pointer foundation to character storage: distinguish a character array from a terminated string, compute capacity requirements, and trace only valid accesses. Use ISO C11/C17. A byte is the unit sizeof measures; sizeof(char)=1, but CHAR_BIT need not be eight. Plain char may be signed or unsigned. No ASCII code values are assumed unless stated. String examples use ordinary basic execution characters.
1. Character, array and string are different concepts
In C, 'A' is an integer character constant of type int; "A" is a string literal that supplies an array of two char objects: the character and a terminating zero character '\0'. The escape '\0' denotes the null character, not digit '0'. The empty string "" occupies one char for its terminator and has length zero. A null pointer is not an empty string; passing a null pointer to strlen violates its requirements.
char a[]="CAT" creates a writable four-element array containing C,A,T,\0. sizeof a is 4, while strlen(a) is 3. char b[3]="CAT" is permitted in C: the terminator is omitted because the explicitly sized array has no room. The three characters fit, but b is not a C string. Calling strlen(b) would seek a terminator beyond the array and has undefined behavior. Do not silently invent a zero after it.
char *p="CAT" makes a pointer to a string literal. C permits this declaration, but modifying any part of that literal has undefined behavior. Prefer const char *p="CAT" to express read-only intent. Conversely char a[]="CAT" owns separate writable storage, so a[0]='B' is valid. sizeof p measures the pointer object, not the pointed-to string; no fixed pointer size is assumed.
2. Capacity includes the final zero
A string of length L needs at least L+1 char elements. Capacity is allocated storage; length is the count before the first zero. They can differ greatly. char s[8]="cat" has capacity 8, length 3 and zeros in the remaining initialized elements. Replacing s[1]='\0' changes length to 1, not capacity; old later characters remain in storage but no longer belong to the visible string prefix.
Worked safe append: char s[6]="cat"; initially bytes are c,a,t,0,0,0. Let n=strlen(s)=3. To append 's' while maintaining a string, check n+1<sizeof s, write s[n]='s', then s[n+1]='\0'. Final bytes c,a,t,s,0,0 have length 4 and capacity 6. Merely overwriting the terminator without ensuring a new in-bounds zero is not a general append algorithm. For arbitrary capacities, the check n<cap−1 requires cap>0 and n already known to be a valid string length; it avoids overflowing n+1 for extreme size_t values.
For copying k known characters into a nonoverlapping destination of capacity cap, require k<cap, then copy indices 0..k−1 and put zero at dst[k]. The source must supply those k readable characters. strcpy requires source termination, sufficient destination capacity and no overlap. strncpy(dst,src,n) is not an automatic safe-string solution: a source of length at least n leaves no terminator, and a shorter source is padded with zeros until n writes occur. Thus destination capacity must be at least n even for short input. Use a deliberate length/capacity contract rather than a function-name shortcut.
3. Array-to-pointer conversion loses the array bound
Except in special contexts such as sizeof and unary &, an array expression converts to a pointer to its first element. For char a[4], a commonly becomes char, while &a is a pointer to the entire array, type char ()[4]. Their pointer arithmetic has different element sizes: a+1 advances one char; &a+1 advances past the whole array. Both may represent legal positions, but a one-past pointer must not be dereferenced.
In void inspect(char s[20]), the parameter is adjusted to char *s; it does not promise that callers supplied twenty elements. sizeof s inside the function is pointer size. Pass a separate capacity to helpers, or use an explicit suitable array contract. A pointer alone does not reveal whether its target is a literal, a local array, an allocation, or a suffix of another array.
Worked suffix trace: char a[]="gate"; char *p=a+1; gives strlen(p)=3 for "ate", sizeof a=5 and p[2]='e'. The valid array indices are 0..4. a+5 is legal as one-past, but *(a+5) is not. p[-1] is valid here because it denotes a[0]; a negative index is not automatically invalid if pointer arithmetic remains within the same array. p[-2] would go before this array and is invalid.
4. Characters, comparisons and safe tracing
Do not assume letters are consecutive in every execution character set. Decimal digits '0'..'9' are consecutive, so after checking c>='0' && c<='9', c-'0' gives a decimal digit. String equality is content comparison, not pointer ==: two distinct arrays holding "cat" compare equal with strcmp, while array pointers identify different objects. strcmp returns a negative, zero or positive int; it is not required to return exactly −1 or 1. For the following character-I/O and classification advice assume INT_MAX>=UCHAR_MAX, as on ordinary implementations. Character-classification functions such as isalpha require EOF or a value representable as unsigned char; cast a possibly negative plain char to unsigned char first. Store getchar's return in int so that every unsigned-char value and EOF can be represented distinctly.
Pitfall checklist
Before strlen/strcmp/copy, prove a reachable in-bounds terminator and readable storage. Before writing, prove writable lifetime and capacity including zero. Track the first zero after every edit. Never infer array length from sizeof(pointer), use uninitialized bytes as a terminator, write through a literal pointer, or dereference one-past.
Original practice: six single-correct MCQs
These original teaching questions are not previous-year questions. Choose one answer.
P01. For char a[]="CAT", what are sizeof a and strlen(a)?
A. 3 and 3 B. 4 and 3 C. 4 and 4 D. Pointer size and 3
Answer: B
A: sizeof includes the terminator.
B: There are four char elements, with three before zero.
C: strlen excludes the terminating zero.
D: a is an actual array in this scope.
P02. Which statement about char b[3]="CAT" is correct in C11/C17?
A. It is illegal solely because the terminator does not fit B. It creates four elements C. It is a valid array initialization, but b is not a terminated string D. strlen(b) is guaranteed to return 3
Answer: C
A: C permits omission of the terminating zero in this initialization.
B: The declared array still has exactly three elements.
C: Only C,A,T are stored, with no terminator.
D: strlen would read beyond the object while searching for zero.
P03. char s[8]="cat"; s[1]=0; now strlen(s) is:
A. 1 B. 2 C. 3 D. 8
Answer: A
A: The first zero is now at index 1.
B: Length counts preceding characters, not the terminator.
C: The old length changed when the earlier zero was written.
D: Eight is capacity, not length.
P04. Inside void f(char s[20]), sizeof s measures:
A. Twenty characters B. The current string length C. Length plus one D. The adjusted pointer parameter
Answer: D
A: Array parameters are adjusted to pointers.
B: sizeof does not scan for a zero.
C: It does not measure the referenced string storage.
D: s has adjusted type char*, so sizeof is pointer size.
P05. char a[]="gate"; char *p=a+1; which is valid?
A. p[-2] B. *(a+5) C. p[-1] D. Writing through char *q="gate"
Answer: C
A: This goes before the array.
B: a+5 is one-past and cannot be dereferenced.
C: p[-1] denotes the valid a[0].
D: Modifying a string literal is undefined behavior.
P06. strncpy(dst,"abcd",4) with writable nonoverlapping dst[4] does what?
A. Writes five bytes including zero B. Writes four characters and no terminator C. Always overflows dst D. Writes only three characters and zero
Answer: B
A: The count limits writes to four here.
B: The source has at least four characters; no zero is copied.
C: Four writes fit, but the result is not a string.
D: strncpy does not reserve the final slot for zero.
Sources and scope
GATE CS 2026 bounded extension of existing foundations. Not a whole-subject completion claim. Examples and questions are original.
Sign in to keep your progress. Sign in