02A-II Stack Arrays Strings
02A-II Stack Arrays Strings
2
Stack Memory Segment
3
The stack memory: last-in, first-out (LIFO)
Stack
Born when a scope begins,
die when it ends. Free space
❑ Heap: dynamic memory
Born with malloc(),
Heap
die with free() or with the program.
Data (Global/Static)
❑ Data: global variables (often read-only)
Born and die with the program.
Code (text)
❑ Code: functions (often read-only)
Born and die with the program. Address 0x000000
4
The stack memory segment
5
compilation
Local variables are typically stored in the
stack in descending memory addresses
int main ()
{
char c = 'd';
int i = 0, j = 0; // assume sizeof(int) = 4
double x = 0; // assume sizeof(double) = 8
}
descending memory addresses
c i j x
'd' 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
0x9F 0x9E 0x9A 0x96
6
Stack and scopes - Example
>call<
int foo( int a, double f )
a
{ f
int b;
...
{
int c;
...
}
...
}
7
Stack and scopes - Example
>call<
int foo( int a, double f )
a
{ f
int b; b
...
{
int c;
...
}
...
}
8
Stack and scopes - Example
>call<
int foo( int a, double f )
a
{ f
int b; b
... c
{
int c;
...
}
...
}
9
Stack and scopes - Example
>call<
int foo( int a, double f )
a
{ f
int b; b
... c
{
int c;
...
}
...
}
10
Stack and scopes - Example
>call<
int foo( int a, double f )
a
{ f
int b; b
... c
{
int c;
...
}
...
}
11
Stack and scopes - Example Return
address
ret
int foo( int a, double f )
{
int b;
...
{
int c;
...
}
...
}
12
The dark side of the stack
void foo( int num )
{
int a;
if( num>1 )
{
foo(num);
}
}
14
Memory and Arrays
15
The array data type
{
int i = 0;
int a[3] = {1, 2, 3}; // sizeof(a) = 3 *
sizeof(int)
}
a[0] a[1] a[2] i
1 0 0 0 2 0 0 0 3 0 0 0 0 0 0 0
0x9C 0xA0 0xA4 0xA8
ascending memory addresses
Array Initialization (1D)
➢ int arr[3] = {3, 4, 5}; // explicit length = 3
➢ rowint
columnarr[3][2] = {{2,5,7},{4,6,7}}; // Err:
arr[0] arr[0] arr[0] arr[1] ...
incompatible
[0] [1] [2] [0]
19
2D Array Memory Map
int a[2][3] = {{2,5,7},{4,6,7}};
a[0] 2 5 7
a[1] 4 6 7
20
2D Array Memory Map
int a[2][3] = {{2,5,7},{4,6,7}};
a[0] a[1]
2 5 7 4 6 7
21
The subscript [] operator –
read/write access to array elements
int arr[] = {3, 4, 5};
arr[1] = 40; // write access {3, 40, 5}
printf("%d\n", arr[2]); // read access 5
arr = {30, 40, 50}; // compile error – cannot
assign
1 5 2 1 3
32 36 40 44 48 52 decimal
hexadecimal
0x20 0x24 0x28 0x2C 0x30 0x34
3. arr[i] 32+i*sizeof(int) = 32 + 4 * i
4. arr[-1] 32+(-1)*sizeof(int) = 28 // Danger: access code segment,
// other variables, etc.
23
Arrays – out-of-bounds access
D. Run-time error
i a[0] a[1] a[2]
. . .
0x0C 0x10 0x14 0x18 hexadecimal
12 16 20 24 decimal
Note – Variable Length Array
(VLA) not allowed in course
C99 allows the array size to be determined at run time:
int m = 10;
. double vla[m]; // VLA, not OK! (in course)
26
Array iteration
and sizeof()
27
Assigning, printing & comparing arrays:
The easy way is the wrong way
C does not provide operators for iterating over all array elements
28
Array comparison – the wrong way
29
Array comparison – the right way
We always know the number of static array elements at
compile-time we can compare them one-by-one
if(a[i] != b[i])
30
Array iteration – a common nasty bug
if(a[i] != b[i])
31
Number of array elements:
sizeof(<array>)/sizeof(<element>)
// Three alternatives:
Printing an array:
for (size_t i = 0; i < na; i++)Code runner L2B.Q3
34
Note: when we pass arrays to functions, we cannot use sizeof()!
{ … }
35
char[] strings
36
A char[] string is a null-terminated
array of characters
int main()
{ '\0' is a special
char str1[] = "hello"; character indicating
the end of a string
char str2[6] = "hello"; (ASCII==0).
} 5 +1
str2 str1
h e l l o 0\ h e l l o 0\ . . .
0x0C 0x10 0x14 0x18 hexadecimal
12 16 20 24 decimal
Equivalently…
int main()
{
char str1[] = {'h','e','l','l','o','\
0’};
char str2[6] = {'h','e','l','l','o','\
0’};
str2 str1
}
h e l l o 0\ h e l l o 0\ . . .
0x0C 0x10 0x14 0x18 hexadecimal
12 16 20 24 decimal
Printing a char[] string
int main()
{
char str[] = "hello";
printf("%s", str); // print till '\0'
}
str
h e l l o 0\
hexadecimal
0x0C 0x10
12 16 decimal
char [] string – don’t lose your '\0'..
int main()
{
char ch = 'a';
char str[] = {'c', 'o', 'd', 'e'};
printf("%s", str);
return 0;
}
c o d e a ?
40
str ch
Q: What is the output?
A. 3
B. 4
C. 5
D. compiler-dependent
A B C D -
vote at hujicppbr.participoll.com
41
String length - C library strlen()
Signature:size_t strlen(const char str[]);
size_t is an unsigned int that indicates size
#include <stdio.h>
#include <string.h>
int main ()
{
char str[] = "hello";
printf ("%zu\n", strlen (str)); // %zu – prints a
size_t
}
str
h e l l o 0\
0x0C 0x10 0x14 0x18 hexadecimal
12 16 20 24 decimal
String length – our own implementation
size_t my_strlen (const char s[])
{
size_t i = 0;
Printing a string:
while(s[i++]!='\0');
Code runner L1A.Q4
return i-1;
}
int main ()
{
char str[] = "hello";
printf("%zu\n", my_strlen (str));
return 0;
}
str
h e l l o 0\
0x0C 0x10 0x14 0x18 hexadecimal
12 16 20 24 decimal
String length – our own implementation
size_t my_strlen (const char s[])
{
size_t i = 0;
Printing a string:
while(s[i++]!='\0');
Code runner L2B.Q4
return i-1;
}
int main ()
{
char str[] = "hello";
printf("%zu\n", my_strlen (str));
return 0;
}
str
h e l l o 0\
0x0C 0x10 0x14 0x18 hexadecimal
12 16 20 24 decimal
Strings as command line
arguments
45
Handling command-line arguments
Command line arguments are passed to main as an array of string –
we will learn about the details later in the course