












































Study with the several resources on Docsity
Earn points by helping other students or get them with a premium plan
Prepare for your exams
Study with the several resources on Docsity
Earn points to download
Earn points by helping other students or get them with a premium plan
A detailed explanation of implementing a generic container in c using a stack as an example. It includes the code for the stack structure, function implementations, and their explanations. It also discusses the importance of hiding the internals of an exposed data structure and the proper usage of the stack operations.
Typology: Study notes
1 / 52
This page cannot be seen from the preview
Don't miss anything!













































typedef s
truc
t^ { void *e
lems; int e
lemSize; intlogLength
int a
llocLength
} stack
typedef s
truc
t^ { void *e
lems; int e
lemSize; intlogLength
int a
llocLength
} stack
Writing a generic container in pure C is hard, andit’s hard for two reasons:1.^
The language doesn’t offer any real support for encapsulation orinformation hiding. That means that the data structures exposeinformation about internal representation right there in the interfacefile for everyone to see and manipulate. The best we can do isdocument that the data structure should be treated as an abstractdata type, and that the client shouldn’t directly manage the fields.Instead, he should just rely on the functions provided to manage theinternals for him.
2.^
C doesn’t allow data types to be passed as parameters. That meansa generic container needs to manually manage memory in terms ofthe client element size, not client data type. This translates to abunch of malloc, realloc, free, memcpy, and memmove callsinvolving void *s. This is the very type of programming that makesC difficult.
typedef s
truc
t^ { void *e
lems; int e
lemSize; intlogLength
int a
llocLength
} stack
void S
tackNew(s
tack *s
,in
telemSize)
void S
tackDispose(s
tack *s
boo
l StackE mpty(const s
tack *s
void S
tackPush(s
tack *s
, const vo
id *
elemAddr)
void S
tackPop(s
tack *s
, vo
id *e
lemAddr
This is what you see as a client, but as a client, you shouldignore the internals of an exposed data structure unless thedocumentation explicitly says otherwise.
typedef s
truc
t^ { void *e
lems; int e
lemSize; intlogLength
int a
llocLength
} stack
void S
tackNew(s
tack *s
,in
telemSize)
void S
tackDispose(s
tack *s
boo
l StackE mpty(const s
tack *s
void S
tackPush(s
tack *s
, const vo
id *
elemAddr)
void S
tackPop(s
tack *s
, vo
id *e
lemAddr
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stack
intStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
val
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
val intStack
sizeo
f(int ) 4 0
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
0
val intStack
sizeo
f(int ) 4 1
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
0
val intStack
00 00 00 00
sizeo
f(int ) 4 2
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
1
val intStack
00 00 00 00
00 00 00 01
sizeo
f(int ) 4 2
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
2
val intStack
00 00 00 00
00 00 00 01
sizeo
f(int ) 4 3
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
3
val intStack
00 00 00 00
00 00 00 01
00 00 00 02
sizeo
f(int ) 4 4
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
3
val intStack
00 00 00 00
00 00 00 01
00 00 00 02
00 00 00 03
sizeo
f(int ) 8 5
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
4
val intStack
00 00 00 00
00 00 00 01
00 00 00 02
00 00 00 03
00 00 00 04
sizeo
f(int ) 8 5
int ma
in(i
nt a
rgc
, char *a
rgv
int va
l; stackin
tStack
StackNew(&in
tStack
, sizeo
f(in
t));
for
(va
l = 0; va
l < 6
; va
l++)
StackPush(&
intS
tack
, &va
l);
whi
le (
!StackE mpty(&
intS
tack)
StackPop(&
intS
tack
, &va
l);
prin
tf("Th
is^ jus
t popped: %d\n"
, va
l);
} StackDispose(&
intStack)
5
val intStack
00 00 00 00
00 00 00 01
00 00 00 02
00 00 00 03
00 00 00 04