Recap: Generic Array
Part of the Object Oriented Programming section of Coddy's C journey — lesson 53 of 61.
Challenge
EasyLet's build a GenericArray container — a flexible data structure that can hold a mix of integers and strings in the same collection using void* pointers.
You'll organize your code across three files:
generic_array.h: Define theGenericArraystruct with three members: avoid**array to hold pointers, anintfor the current count, and anintfor capacity. Declare the function prototypes for creating the array, adding elements, retrieving elements by index, and freeing the array.generic_array.c: Implement your container's functionality:create_array— allocates a GenericArray with a given initial capacity and initializes count to 0add_element— stores avoid*pointer at the next available slot and increments count (assume capacity is sufficient)get_element— returns thevoid*at the specified indexfree_array— frees the items array and the GenericArray struct itself
main.c: Demonstrate your generic array by storing both integers and strings. Read the number of elements to add, then for each element read a type indicator (ifor integer,sfor string) followed by the value. After adding all elements, iterate through the array and print each value. For integers, print the number directly. For strings, print the text directly.
Your program will receive:
- The number of elements to add
- For each element: a type indicator (
iors) followed by the value
When adding integers, allocate memory for the int and store the pointer. When adding strings, allocate memory and copy the string. When retrieving, cast back to the appropriate type to print.
Important: To track types for printing, you can use a simple parallel array of type indicators in main, or store the type indicator character alongside each element.
Example output when inputs are 3, then i 42, s Hello, i 100:
42
Hello
100Example output when inputs are 4, then s World, s Generic, i -5, s Arrays:
World
Generic
-5
ArraysRemember to use include guards in your header file. The container itself doesn't need to know what types it stores — it just holds void* pointers. The responsibility of knowing the type falls on the code that adds and retrieves elements.
Try it yourself
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "generic_array.h"
int main() {
int n;
scanf("%d", &n);
// TODO: Create a GenericArray with capacity n
// TODO: Create a parallel array to track types (char array of size n)
// TODO: For each element:
// - Read the type indicator (i or s)
// - Read the value
// - If integer: allocate memory for int, store value, add to array
// - If string: allocate memory for string, copy value, add to array
// - Store the type indicator in your parallel array
// TODO: Iterate through the array and print each element
// - Check the type from your parallel array
// - Cast the void* back to appropriate type and print
// TODO: Free all allocated memory (integers, strings, and the array)
return 0;
}
All lessons in Object Oriented Programming
1Modular Programming Basics
Header FilesInclude GuardsSource FilesStatic FunctionsRecap: Modular Calculator4Encapsulation
Opaque Pointers ConceptDefining Opaque StructsGetters and SettersValidation in SettersRecap: Secret Box7Function Pointers
Declaring Function PointersCalling Function PointersTypedef for Function PointersPassing Functions as ArgumentsRecap: Calculator Dispatch10Generic Containers
Void Pointers RecapGeneric WrapperGeneric SwapGeneric CompareRecap: Generic Array2Objects and Methods
Structs as ObjectsThe 'Self' PointerConst CorrectnessPointer vs ValueHelper MethodsRecap: Point Manager5Project: Simple Bank Account
Project SetupImplementation of Account3Object Lifecycle
Constructor PatternDestructor PatternStack InitializationDeep CopyRecap: String Wrapper6Inheritance via Composition
Struct EmbeddingThe First Member RuleAccessing Parent MembersUpcastingRecap: Shape Hierarchy