Lecture 8: Strings and Dynamic Memory
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Strings
*** strings are just arrays of characters with the special convention
that they always end in '\0' - the null character
char s[3] = "hi"
*** why 3 characters?
==> leave room for '\0'
*** this is short for:
char s[3] = { 'h', 'i', '\0'};
*** alternative:
char s1[] = "hi";
*** printing:
printf("%s", s1);
*** always print out a string as above rather than:
printf(s1);
*** why? what if s1 was "%d"!!!
- Eg:
int len(char s[])
{
int i;
for (i=0; i != '\0'; i++)
;
return i;
}
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- what if we want to copy a string?
First try:
char s1[100] = "hi";
char *s2;
s2 = s1; /* this is a pointer assignment, the elements are not copied */
s1 = "bye";
printf("%s, %s", s1, s2); /* we will print: "bye, bye" */
- strings are pointers to characters or arrays. We CANNOT use = to
assign one string variable the contents of another.
- a second try:
char *copy(char *s)
{
char res[100];
int slen, i;
slen = len(s);
for(i=0; i< slen; i++)
res[i] = s[i];
res[i] = '\0';
return res;
}
- this doesn't work either. Only the pointer is copied on return
from a function. All of the elements of the character array are left
on the stack and "disappear" when the function returns.
- remember:
- Local variables "disappear" after the function is done
- integers, floats, structs, chars, etc results are all *copied*
from the stack, just as they are copied to the stack as parameters
- pointers(arrays) are copied but NOT the objects they point to.
- we need a way to allocate more memory for the new copy of the string.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Dynamically Allocated Memory:
- the 3rd memory area: the heap
1) Static memory: used for global variables: they last throughout the
program
2) Stack memory: used for local variables + parameters: they last
for one function call
3) Heap memory: dynamically allocated: allocation and deallocation
not automatic - lasts for as long as the programmer decides
Sizeof:
- In order to allocate something, we need to know how much space to allocate.
- eg: ints may be 4 bytes, doubles may be 8 bytes.
struct date { int month, day, year; } may be 12 bytes.
- we use the function sizeof to find out how big a type is:
sizeof(int);
sizeof(struct date);
sizeof(char);
- we don't use sizeof on arrays or pointer types(in general)
Malloc + Free:
- malloc returns a pointer to memory you can use
- free returns the memory pointed to
struct date *p;
p = (struct date *)malloc(sizeof(struct date));
(*p).month = 10;
(*p).day = 16;
(*p).year = 97;
free(p);
- every use of malloc must be balance by a free somewhere in your program.
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Back to copying strings:
char *strcpy(char *s)
{
char *cpy;
int slen, i;
/* allocate space for the string. Remember 1 extra char space
for the null character
*/
slen = len(s) + 1;
cpy = (char *)malloc(slen*sizeof(char));
for(i=0; i