BCA SCHOOL
Programming Tutorials • Notes • Practical • Books
LATEST TUTORIALS

String Arrays in C: 2D char Arrays & Pointers | Unit 4 | BKNMU BCA

by BCA School •

BKNMU Junagadh  |  BCA Sem 1  |  Unit 4



String Arrays (Array of Strings) in C Programming

Complete Guide to Storing Multiple Strings using 2D char Arrays and Arrays of char Pointers, with Memory Analysis and Code Examples

BKNMU Junagadh BCA Sem 1 Unit 4 Array of Strings 2D char Array string.h
In simple words: A string in C is a 1D array of characters (char) terminating with a null character (\0). To store multiple independent strings—like a list of 5 student names or 7 days of the week—we need a structure that can hold multiple 1D arrays. This is achieved in C using two primary methods: a Two-Dimensional (2D) Array of Characters, or an Array of Character Pointers. This guide breaks down both approaches tailored for BKNMU BCA Semester 1 (Unit 4).
📖 Core Approaches to String Arrays

The two main structural architectures for handling arrays of strings are:

Method A: 2D char Array

1. Fixed-Width Table

Organizes strings into rows and columns char[R][C]. Every string must fit within the fixed maximum column width C.

Method B: Array of Pointers

2. Jagged/Ragged Array

Stores only memory addresses (pointers) in a 1D array char*[]. Each pointer links to a string literal stored elsewhere, allowing varied lengths.

Method A Memory

3. Rectangular Allocation

Allocates a continuous rectangular block of bytes (R × C). Shorter strings cause internal fragmentation (wasted bytes after \0).

Method B Memory

4. Optimized Storage

No wasted space for variable-length strings, but requires extra memory to store the pointer addresses themselves (4 or 8 bytes per string).

1️⃣ Master Table: Comparison & Initialization Patterns

A complete architectural reference comparing syntax, memory mapping, and accessibility:

Comparison Factor Method A: 2D char Array Method B: Array of char Pointers
Declaration char names[3][10]; char *names[3];
Conceptual Model A table/matrix of characters. A list of addresses pointing to character sequences.
Initialization = {"Jan", "Feb", "Mar"}; = {"Jan", "Feb", "Mar"};
Accessing String i names[i] (acts as pointer to row `i`) names[i] (holds address of string `i`)
Modifiability Strings are modifiable (stored in RAM Stack/Data segment). Strings are literals (usually read-only constant data segment).
Total Memory ROWS × MAX_COLS bytes allocated contiguously. `Pointer_size × COUNT` + total string lengths (+ nulls).
ℹ️ Memory Mapping Analogy:
  • Method A (2D Array): Like a parking lot with fixed-size spaces. Even a bicycle occupies a full car space, wasting the rest.
  • Method B (Pointer Array): Like a list of locker numbers written on a notepad. Each notepad entry (pointer) tells you exactly where to find that variable-sized locker somewhere else in the building (memory).
💻 Practical Code Examples

1. Working with 2D char Array (Modifiable Strings with Fixed Width):

#include <stdio.h>
#include <string.h>

int main() {
    // Declaration: 3 rows, 10 columns max each
    char colors[3][10] = {"Red", "Green", "Blue"};
    int i;

    printf("Original colors list:\n");
    for (i = 0; i < 3; i++) {
        printf("colors[%d] = %s (Base: %p)\n", i, colors[i], &colors[i]);
    }

    // Modification is valid here:
    strcpy(colors[1], "Yellow"); 

    printf("\nUpdated colors list:\n");
    for (i = 0; i < 3; i++) {
        printf("colors[%d] = %s\n", i, colors[i]);
    }

    return 0;
}

2. Working with Array of char Pointers (Memory Optimized, Read-Only):

#include <stdio.h>

int main() {
    // Array of 4 pointers to string literals
    char *days[4] = {"Monday", "Tuesday", "Wednesday", "Thursday"};
    int i;

    printf("Weekdays list (Pointers):\n");
    for (i = 0; i < 4; i++) {
        // colors[i] holds address of literal, &colors[i] holds address of pointer itself
        printf("Pointer Address: %p | points to literal at: %p | Value: %s\n", 
                &days[i], days[i], days[i]);
    }

    // WARNING: Modifying literals causes UB: colors[1][0] = 'Z'; (WRONG)
    // Pointer can be reassigned: days[1] = "Holiday"; (VALID)

    return 0;
}
🔄 Step-by-Step Flow: Accessing elements in 2D char Array
1

Base Address Calculation (Row)

Execution starts. To access `colors[i]`, compiler uses `Base + i × MAX_COLS` to find the start address of that specific row contiguous block.

2

String Processing (NULL search)

When used with `%s`, the function starts reading from the row's base address and proceeds horizontally character-by-character along the row segment.

3

Row Teardown

The reading stops immediately upon encountering the null character `\0`. The remaining allocated columns (wasted space) are ignored, enforcing null-termination rules.

💡 Critical Exam Insight: Omitted Row Size in 2D strings: When initializing a 2D char array, you can omit the row bound (first dimension) but MUST provide the column bound (second dimension, max string width + null), e.g. `char s[][10] = {...};` is valid; `char s[3][] = {...};` is an error.
⚠️ Dangerous Operation: Writing past Column Width in 2D Arrays: If you declare `char s[3][5]` and `strcpy(s[0], "HelloWorld")`, C won't check boundaries. This overwrites neighbor memory blocks, corrupting string `s[1]` or causing segmentation faults. Always ensure `MAX_COLS` accommodates the null terminator.
📝 Quick Revision — Key Exam Points
  • Definition: A structure to store multiple strings under one variable identifier.
  • Method A (2D char Array): Grid format `char[R][C]`; Continuous memory; potentially wastes space (internal fragmentation). Strings modifiable.
  • Method B (Array of char Pointers): Jagged list `char*[]`; Non-contiguous literals; optimized storage; Strings read-only literals.
  • Access Syntax: `arr[i]` accesses the $i$-th string directly in both methods (acts as base pointer).
  • Null Termination: In 2D arrays, every row acts as an independent string terminating with `\0`.