Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 C - Memory Simple Types Arrays Pointers Pointer to Pointer Multi-dimensional Arrays Dynamic Memory Allocation.

Similar presentations


Presentation on theme: "1 C - Memory Simple Types Arrays Pointers Pointer to Pointer Multi-dimensional Arrays Dynamic Memory Allocation."— Presentation transcript:

1 1 C - Memory Simple Types Arrays Pointers Pointer to Pointer Multi-dimensional Arrays Dynamic Memory Allocation

2 2 Memory and PointersSIMPLE TYPES 159.234 When we create a variable in a program, we use the name of the variable to access its value. The computer only knows about memory locations (addresses) and contents (values). The compiler translates our instructions into something meaningful to the computer, int i, j; allocates storage for two integers (sizeof(int), 4 bytes) and remembers their addresses i may be at address 100 and j at 104. i = j; 104 100 is translated by the compiler into: copy 4 bytes at location 104 to location 100

3 3 C-MemorySIMPLE TYPES 159.234 When we include a numeric or character constant in a program: i = 6; i = 6; 6 the compiler places the value '6' into the machine instruction. If we also have j = 6; j = 6; 6 there will be two '6' s in our executable file.

4 4 C-MemoryARRAYS 159.234 When we create an array, the compiler allocates as much memory as requested and remembers the address of the first element. char s[80]; allocates 80 bytes starting at 108 *. *that is, continuing with our previous example

5 5 C-Memory Array name 159.234 The name 's' is different from 'i‘ 'i' refers to the value stored at address 100 's' refers to the address 108 We are not allowed to say: s = 'a'; To access the value stored at s: s[0] = 'a'; or (*s) = 'a'; The indirection operator * s is an address. The indirection operator * accesses the contents stored at the address.

6 6 C-Memory ARRAYS 159.234 s[i] *(s+i) s[i] is a shorthand way of writing *(s+i) We can add an integer to an address – the result is an address. (The integer is first multiplied by the size of the element being pointed to) The result of subtracting two addresses is an integer. The number of elements. We cannot multiply an address with an integer. Adding addresses Subtracting addresses Multiplying addresses

7 7 C-Memory ARRAY CONSTANTS 159.234 A string cannot be 'part of an instruction'. 48 Instructions are fixed length – 4 or 8 bytes. The compiler allocates memory for the string and remembers its location. strcpy(s,"Napoleon"); "Napoleon" is stored in memory at address 188 9 bytes are allocated (8 plus a NULL). The text "Napoleon" is stored in the executable file and is placed at location 188 when the program starts.

8 8 C-Memory ARRAY CONSTANTS 159.234 If the constant appears twice in the program: strcpy(s,"Napoleon"); strcpy(t,"Napoleon"); the compiler has the choice of creating two separate memory areas each with the word "Napoleon", or using the same area for both. To save space it will normally do the latter.

9 9 C-Memory Size of ARRAYS 159.234 Do we need to say how big arrays are? - Yes, otherwise the compiler does not know how many bytes to allocate. What about when we initialise strings? char s[] = "Napoleon"; We don't need to give the size of the string – but the compiler works it out itself. See AddressArray.cpp

10 10 C-Memory 2-D ARRAYS 159.234 What about 2 dimensional arrays? The compiler fools us a little – there is no such thing as a 2D array. Only 1D arrays. char array[20][80]; allocates 1600 bytes of memory. 'array' is the address of the first byte. array[3][5] is converted by the compiler to: *(array + 3*80 + 5) similarly for 3 and 4 dimensional arrays. See AddressArray.cpp

11 11 C-Memory Specifying the array dimension at run-time 159.234 Can we specify the dimension at run-time? - Not unless we use pointers. A pointer is a variable that contains an address. char *p; Now we have two addresses! p is a variable, its value is an address. This is the address we normally want. p is somewhere in memory so it has an address associated with its own position. & The & operator gets the address of a variable. char *p; char c; p = &c; p is at location 100 c is at location 104 the contents of p is 104. The indirection operator * accesses the contents of an address

12 12 C-MemoryUsing the subscripting operator with pointers 159.234 (*p) = ‘N'; pointers and arrays look very similar! We can use the [ ] operator with pointers p[0] = ‘N'; 0 p points to a single character, so we can only access the 0'th element. fail Writing to p[1] causes the program to fail. If we allocate memory from the heap, p can point to as many bytes as we want: Subscript operator void *malloc(size_t size);

13 13 C-Memorymalloc 159.234 p = (char *)malloc(80*sizeof(char)); allocates 80 bytes. p contains the address of the first character. malloc can have a variable as an argument, so the size of the 'string' p can be set at runtime. char *p; int i; printf("How big is the string:"); scanf("%d", &i ); p = (char *)malloc(i*sizeof(char)); void *malloc(size_t size);

14 14 C-Memory Declaring an ARRAY vs. Declaring a Pointer 159.234 char s[80]; char *p; p = (char *)malloc(80*sizeof(char)); p and s behave very much the same. p[12] = 'a'; s[12] = 'b'; strcpy(p,"Napoleon"); strcpy(s,"Napoleon"); printf("%s",p); printf("%s",s); There is a difference: char s[80]; char *p; char c; p = &c; this is certainly ok s = &c; this is NOT s s is not variable. Its value cannot change.

15 15 C-Memory ARRAYS 159.234 Be very careful when 'initialising' a pointer char *p = "Napoleon"; If "Napoleon" is a constant, used in many places in the program then p[0] = 'X'; Will change all “Napoleon"s into "Xapoleon".

16 16 C-Memory 2D arrays on the heap? 159.234 Several possibilities, but the syntax becomes very difficult. char (*p)[80]; p = (char (*)[80])malloc(10*80*sizeof(char)); p[0][0] = 'a'; is correct (and the round brackets are required!) typedef char string[80]; string *q; q = (string *)malloc(10*sizeof(string)); is equivalent and looks better, although the typedef is a bit strange. char (*p)[80]; //pointer to a char array char *(p[80]); //array of pointers to char only the very brave or foolish use these.

17 17 C-Memory POINTER TO A POINTER 159.234 A third method is more common and uses a pointer to a pointer. char **p; We have to do more work to set this up as a 2D array, but we have a lot more flexibility in the size of the array. The number of rows in the array is set first, by making p point to an array of pointers. p = (char **)malloc(rows*sizeof(char *)); each pointer is then set to point to an array of characters. for (i=0; i<row; i++) { p[i] = (char *)malloc(cols*sizeof(char)); } p is a pointer to a pointer p[i] is a string p[i][j] is a character

18 18 C-Memory 2-D Array doesn’t have to be square 159.234 We can still use the [] operator to access elements of each array. We do not need to allocate the same number of characters to each string – the array does not have to be square. for (i=0;i<row;i++) { (i+1) p[i] = (char *)malloc((i+1)*sizeof(char)); } When we have finished with memory allocated from the heap, we must give it back. char *p; p = (char *)malloc(80*sizeof(char)); … free(p); In the case of pointers to pointers, we must be careful to free memory in the correct order. for (i=0;i<row;i++) { free(p[i]); } free(p); Do not access heap memory after it has been free'd.

19 19 C-Memory How does f ff free know how much memory to release? 159.234 malloc has to remember how many bytes were allocated. How it does this is not specified, but one common way is to allocate an extra 4 bytes, at the start, that contain the size. If we write to p[-1] at any time, then our program will explode when we free(p) stack Local variables are kept on a 'stack'. This is created each time a function is called. The stack is destroyed when a return is executed. The stack is not set to zero each time it is created (too expensive) – and so local variables contain arbitrary data. Local variables need to be initialised.

20 20 C-Memory POINTERS 159.234 A pointer may be on the stack – but what it points to may be on the heap. Failing to free heap memory before exiting a function will leave memory on the heap that no longer has a pointer pointing to it. memory leak This memory can never be recovered – it is called a memory leak. Get into the habit of always freeing memory. Even when the program exits.

21 21 C-Memory POINTERS 159.234 When a function wants to change the value of an actual parameter, an address must be passed to the function. For strings the syntax looks ok, because the name is itself an address: strcpy(s,“Napoleon"); … void strcpy(char *p, char *q) { inside strcpy we access the original using p[i]. To alter an integer the syntax is more clumsy twice(&i); … void twice(int *ip) { (*ip) = (*ip)*2; }

22 22 C-Memory POINTERS 159.234 We have to be brave to alter a pointer! char *s; allocate_and_check(&s); … void allocate_and_check(char **p) { (*p) = (char *)malloc(80); if ((*p) == NULL) { … It is a lot easier to use return values. newdelete C++ tidies up the problems associated with malloc and free by introducing 2 new keywords, new and delete. Reference parameters also are a new feature, to make it easier to alter arguments.

23 23 C-Memory POINTERS & MULTIDIMENSIONAL ARRAYS 159.234 int (*x)[20]; int x[10][20]; rather than … … … x (x +1) (x +2) First array Second array Third array … … *(x +2) *(x +2)+5 *(*(x +2) + 5) 2D INTEGER ARRAY (x+1) automatically takes into account the number of elements in an array See AddressArray2.cpp


Download ppt "1 C - Memory Simple Types Arrays Pointers Pointer to Pointer Multi-dimensional Arrays Dynamic Memory Allocation."

Similar presentations


Ads by Google