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