1 c - memory simple types arrays pointers pointer to pointer multi-dimensional arrays dynamic memory...
TRANSCRIPT
1
C - MemoryC - Memory
• Simple Types• Arrays• Pointers• Pointer to Pointer• Multi-dimensional Arrays• Dynamic Memory Allocation
2
Memory and PointersSIMPLE TYPESSIMPLE 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 int ii, , jj;;allocates storage for two integers (sizeof(int), 4 bytes) and remembers their addresses
ii may be at address 100 and may be at address 100 and jj at 104. at 104.ii = = jj;;
is translated by the compiler into: copy 4 bytes at location 104104 to location 100100
3
C-Memory
SIMPLE TYPESSIMPLE TYPES
159.234
When we include a numeric or character constant in a program:
i = 6;i = 6;
the compiler places the value '66' into the machine instruction.If we also have
j = 6;j = 6;
there will be two '66' s in our executable file.
4
C-Memory
ARRAYSARRAYS
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];char s[80];
allocates 80 bytes starting at 108*.
*that is, continuing with our previous example*that is, continuing with our previous example
5
C-MemoryArray name
159.234
The name 's' is different from 'i‘
'i' refers to the value stored at address 100's' refers to the address 108We are not allowed to say:
s = 'a';s = 'a';
To access the value stored at s:
s[0] = 'a';s[0] = 'a';or (*s) = 'a';(*s) = 'a';
s is an address. The indirection operator * The indirection operator * accesses the contents stored at the address.
6
C-MemoryARRAYS
159.234
s[i] s[i] is a shorthand way of writing *(s+i)*(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
C-MemoryARRAY CONSTANTS
159.234
A string cannot be 'part of an instruction'. Instructions are fixed length – 44 or 88 bytes.
The compiler allocates memory for the string and remembers its location.
strcpy(s,"Napoleon");strcpy(s,"Napoleon");
"Napoleon" is stored in memory at address 1889 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
C-MemoryARRAY 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
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.cppSee AddressArray.cpp
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.cppSee AddressArray.cpp
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 100c is at location 104the contents of p is 104.
The indirection operator * accesses the contents of an address
12
C-Memory
Using the subscripting operator with pointersUsing 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';
p points to a single character, so we can only access the 00'th element.
Writing to p[1] causes the program to failfail.
If we allocate memory from the heap, p can point to as many bytes as we want:
Subscript operatorSubscript operator
void *malloc(size_t void *malloc(size_t sizesize););
13
C-Memory
mallocmalloc
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 void *malloc(size_t sizesize););
14
C-MemoryDeclaring 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
ss is not variable. Its value cannot change.
15
C-MemoryARRAYS
159.234
Be very careful when 'initialising' a pointerchar *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
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
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 pointerp[i] is a stringp[i][j] is a character
18
C-Memory2-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++) { p[i] = (char *)malloc((i+1)(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
C-Memory
How does freefree 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)
Local variables are kept on a 'stackstack'. 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 Local variables need to be need to be initialised.initialised.
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.
This memory can never be recovered – it is called a memory memory leakleak.
Get into the habit of always freeing memory. Even when the program exits.
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
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.C++ tidies up the problems associated with malloc and free by introducing 2 new keywords, newnew and deletedelete.Reference parameters also are a new feature, to make it easier to alter arguments.
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+1x+1) ) automatically takes automatically takes into account the number into account the number of elements in an arrayof elements in an array
See See AddressArray2.cppAddressArray2.cpp