Pointers and Memory Allocation – part 2 -L. Grewe.
-
date post
20-Dec-2015 -
Category
Documents
-
view
222 -
download
0
Transcript of Pointers and Memory Allocation – part 2 -L. Grewe.
![Page 1: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/1.jpg)
Pointers and Memory Allocation – part 2-L. Grewe
![Page 2: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/2.jpg)
2
Objectives
•Pointers to Functions
•More potential Issues with Pointers - advanced
![Page 3: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/3.jpg)
Pointers to Functions(this is NOT passing pointers as arguments to functions!!!
This is a pointer pointing to a function itself!!!!!!)
A pointer can also store the address of a function
A function name is the address in memory of the start of the function
Function pointers can be
– Passed to a function
– Returned to functions
– Stored in arrays
– Assigned to other function pointers
![Page 4: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/4.jpg)
An Array of Pointers to Functions#include <stdio.h>
void fun1(void);
void fun2(void);
void fun3(void);
int main(){
/*declare an array of pointers to functions*/
void (*array[3])(void) = {fun1,fun2,fun3};
int i;
for (i=0;i<3;i++)
(*array[i])();/*make a function call*/
return 0; /*output: 1st 2nd 3rd */
}
void fun1(void){printf("1st ");}
void fun2(void){printf("2nd ");}
void fun3(void){printf("3rd ");}
![Page 5: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/5.jpg)
Alternative Code#include <stdio.h>
void fun1(void);
void fun2(void);
void fun3(void);
int main(){
void (*array[3])(void) = {fun1,fun2,fun3};
/*declare an array of pointers to functions*/
int i;
for (i=0;i<3;i++)
array[i](); /*or (*array[i])(); */
return 0; /*output: 1st 2nd 3rd */
}
void fun1(void){printf("1st ");}
void fun2(void){printf("2nd ");}
void fun3(void){printf("3rd ");}
![Page 6: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/6.jpg)
Pointers to Functions
void (*array[3])(void)={fun1,fun2,fun3};
“array” is an array of 3 pointers to 3 functions with no arguments and return type void
(*array[i])(void); //THESE ARE THE SAME
array[i]();
![Page 7: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/7.jpg)
An Array of Pointers to Functions 2#include <stdio.h>
int fun1(int);
int fun2(int);
int fun3(int);
int main(){
int (*array[3])(int) = {fun1,fun2,fun3};
int i;
for (i=0;i<3;i++)
printf("%d ",(*array[i])(i)); /*1 3 5*/
/* printf("%d ", array[i](i)); */
return 0;
}
int fun1(int x){return x+1;}
int fun2(int x){return x+2;}
int fun3(int x){return x+3;}
Just some new functionsfun1, fun2, fun3With parameters
![Page 8: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/8.jpg)
Pointers to Functions 2
int (*array[3])(int)={fun1,fun2,fun3};
“array” is an array of 3 pointers to 3 functions with one int argument and return type int
(*array[i])(i);
array[i](i);
The function is dereferenced and integer “i” is passed as an argument to the function
![Page 9: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/9.jpg)
Pointers to functions: WHY?
9
They allow for a certain amount of polymorphism:
– “poly” (many) + “morph” (shape)
– A polymorphic language can handle a range of different data types (“shapes”?) with a single statement
![Page 10: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/10.jpg)
Pointers to functions: safety concerns
10
What if uninitialized function pointer value is accessed?
– Safest outcome: memory error, and program is terminated
– But what if the “garbage” value is a valid address?
• Worst case: address contains program instruction –execution continues, with random results
• Hard to trace the cause of the erroneous behavior
![Page 11: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/11.jpg)
Pointer and Memory Failures re-visited and Advanced
11
![Page 12: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/12.jpg)
Memory-related bugs
Dereferencing bad pointers
Reading uninitialized memory
Overwriting memory
Referencing nonexistent variables
Freeing blocks multiple times
Referencing freed blocks
Failing to free blocks
![Page 13: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/13.jpg)
Reading uninitialized memoryAssuming that heap data is initialized to zero
/* return y = Ax */int *matvec(int **A, int *x) { int *y = malloc(N*sizeof(int)); int i, j;
for (i=0; i<N; i++) for (j=0; j<N; j++) y[i] += A[i][j]*x[j]; return y;}
![Page 14: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/14.jpg)
Overwriting memory
Allocating the (possibly) wrong sized object
int **p;
p = malloc(N*sizeof(int));
for (i=0; i<N; i++) { p[i] = malloc(M*sizeof(int));}
![Page 15: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/15.jpg)
Overwriting memory
Off-by-one
int **p;
p = malloc(N*sizeof(int *));
for (i=0; i<=N; i++) { p[i] = malloc(M*sizeof(int));}
![Page 16: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/16.jpg)
Overwriting memoryNot checking the max string size
char s[8];int i;
gets(s); /* reads “123456789” from stdin */
Basis for classic buffer overflow attacks• 1988 Internet worm• modern attacks on Web servers• AOL/Microsoft IM war
![Page 17: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/17.jpg)
Buffer overflow attacksDescription of hole:
– Servers that use C library routines such as gets() that don’t check input sizes when they write into buffers on the stack.
– The following description is based on the IA32 stack conventions. The details will depend on how the stack is organized, which varies between compilers and machines
64 bytesfor buffer
return addr
Saved regs. and Local vars
proc a() { b(); # call procedure b}
proc b() { char buffer[64]; # alloc 64 bytes on stack gets(buffer); # read STDIN line into buf}
Stack frame
for proc a
%ebpStack frame
for proc b
%ebp
increasingaddrs
![Page 18: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/18.jpg)
Buffer overflow attacksVulnerability stems from possibility of the gets() routine overwriting the return address
for b.
– overwrite stack frame with
• machine code instruction(s) that execs a shell
• a bogus return address to the instruction
proc a() { b(); # call procedure b} # b should return here, instead it # returns to an address inside of buffer
proc b() { char buffer[64]; # alloc 64 bytes on stack gets(buffer); # read STDIN line to buffer}
Stack region overwritten by gets(buffer)
exec(“/bin/sh”)
New return addr
Saved regs. and Local vars
Stack frame
for proc a
paddingStack frame
for proc b
%ebp
incraddrs
![Page 19: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/19.jpg)
Overwriting memoryReferencing a pointer instead of the object it points to
int *BinheapDelete(int **binheap, int *size) { int *packet; packet = binheap[0]; binheap[0] = binheap[*size - 1]; *size--; Heapify(binheap, *size, 0); return(packet);}
![Page 20: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/20.jpg)
Overwriting memory
Misunderstanding pointer arithmetic
int *search(int *p, int val) { while (*p && *p != val) p += sizeof(int);//you should increment //array by 1 only //you are missing elements
return p;}
![Page 21: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/21.jpg)
Referencing nonexistent variables
Forgetting that local variables disappear when a function returns
int *foo () { int val; return &val;}
![Page 22: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/22.jpg)
Freeing blocks multiple times
x = malloc(N*sizeof(int));// ….<manipulate x>free(x);
y = malloc(M*sizeof(int));//…<manipulate y>free(x);
![Page 23: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/23.jpg)
Referencing freed blocks
x = malloc(N*sizeof(int));//….<manipulate x>free(x);...
y = malloc(M*sizeof(int));for (i=0; i<M; i++) y[i] = x[i]++;
![Page 24: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/24.jpg)
Failing to free blocks(memory leaks)
Run out of memory as you repeatedly call function …foo(), foo(), foo() ….
foo() { int *x = malloc(N*sizeof(int)); ... return;}
![Page 25: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/25.jpg)
Failing to free blocks(memory leaks)
Freeing only part of a data structure
struct list { int val; struct list *next;};
foo() { struct list *head = malloc(sizeof(struct list)); head->val = 0; head->next = NULL; <create and manipulate the rest of the list> ... free(head); //not freeing other part of list created. return;}
![Page 26: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/26.jpg)
Dealing with memory bugs
Conventional debugger (gdb)
– good for finding bad pointer dereferences
– hard to detect the other memory bugs
Debugging malloc
– wrapper around conventional malloc
– detects memory bugs at malloc and free boundaries
• memory overwrites that corrupt heap structures
• some instances of freeing blocks multiple times
• memory leaks
– Cannot detect all memory bugs
• overwrites into the middle of allocated blocks
• freeing block twice that has been reallocated in the interim
• referencing freed blocks
![Page 27: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/27.jpg)
Dealing with memory bugs (cont.)
Binary translator (i.e. Purify-IBM product)
– powerful debugging and analysis technique
– rewrites text section of executable object file
– can detect all errors as debugging malloc
– can also check each individual reference at runtime
• bad pointers
• overwriting
• referencing outside of allocated block
Garbage collection– let the system free blocks instead of the programmer.
![Page 28: Pointers and Memory Allocation – part 2 -L. Grewe.](https://reader031.fdocuments.us/reader031/viewer/2022032015/56649d4e5503460f94a2d5e7/html5/thumbnails/28.jpg)
Pointer and Memory Allocation Tips
• Use Pointers only when you need to.
• Pointer problems can be the most difficult to debug
• Whenever you allocate memory – think immediately where/if you need to deallocate it
• Use Data Structures implemented in C++ Collections already provided when possible –as they are written to take care of potential problems like class copying we saw previously.
28