Dynamic Allocation
1. Calling Function
-When calling a function, the array is created on the stack. And the variables on the stack exit only until the function ends. After it ends, the stack will be used for a new stack frame.
2. Dynamic memory allocation
-Dynamic memory allocation allows a programmer to request a specific amount memory to be allocated on the heap. Since it is not in the stack, it is not freed when the function returns.
-Instead, the programmer must explicitly free the memory when using it.
-The heap changes sizes as program runs.
-The memory allocation library manages the free memory in the heap. When a request cannot be satisfied from the existing free blocks of memory, the allocation library requests that the upper boundary of the heap be increased.
-We can use realloc function to allocate a new block of memory, copying original one to that place and free the old one.
3. Dynamic memory allocation
-We can use malloc to allocate dynamic memory.
void * malloc(size_t size);
void * means the return value has type void *: a pointer to something.
size_t is an alias for an appropriately-size unsigned int type
size is how many bytes to allocate
-malloc requires that you tell it how much memory you need in bytes! But writing a specific number of bytes is incorrect in almost all cases.
1) Portability. The ability to compile code in different system and still have it work correctly.
2) Maintainability.
-We should let the C compiler calculate the size of the type for us using the sizeof operator
malloc(sizeof(int))
-The sizeof operator is evaluated at compile time, not run-time.
-A good way to use call malloc is to use
int * myArray = malloc (6 * sizeof())
In this way, the call to malloc would continue to be correct with no additional changes.
-When we use
p = malloc (6 * sizeof(*p))
malloc function evaluates a pointer to that memory location. And when we perform a assignment statement, we are taking the address location of new area in memory, and we are writing that address to p.
4. Failure
-If there's no enough space for heap to fulfill current request, malloc will return NULL instead of a valid pointer. So, it is a good idea to check if the value is NULL or not before using this pointer.
5. Fixing initArray
-After learning about malloc, we can use it to fix previous problem.
int * initArray (int howLarge) {
int * array = malloc (howLarge * sizeof (*array));
if(array != NULL) {
for(int i = 0; i < howLarge; i++) {
array[i] = i;
}
}
return array;
}
6. Shallow vs Deep Coping
polygon_t * o2 = p1;
It just copies pointer, not he object it points to.
-If we use malloc, we could create a copy, but its sub-element points to the same as original ones. If we change original sub-element, then it will also change. This is shallow copy.
-If we want two completely distinct polygon objects, we should make a deep copy.
polygon_t * p2 = malloc(sizeof(*p2));
p2 -> num_points = p1 -> num_points;
p2 -> points = malloc(p2->num_points * sizeof(*p2->points));
for(size_t i = 0; i < p2 -> num_points; i++) {
p2->points[i] = p1->points[i];
}
COMPARASION
-polygon_t * p2 = p1; //points to the same address
-polygon_t * p2 = malloc(sizeof(*p2)); //different object, but sub-element points to the same address
*p2 = *p1;
And the statement in previous section. //deep copy
-segmentation fault occurs when a program attempts to access a memory location that it is not allowed to access
-dangling points means you want to access a location that has been deallocated in memory.
7. free
-Memory on the heap must be explicitly freed by the programmer. We use free to free the memory.
void free (void * ptr)
Here void means memory is freed, but user receives no explicit feedback
void * means the type matches the return value of malloc
-If p points at something other than the start of a block in the heap, it is an error and bad things will happen.
-We should firstly free sub-pointers in the pointer, then free the pointer.
8. Memory Leaks
-When you lose all references to a block of memory, and the memory is still allocated, this is said to be leaked memory.
-Programs that go slower after one day or two may be the result of leaked memory.
-We should run our programs in Valgrind to be sure we get the following message:
All heap blocks were freed -- no leaks are possible
9. Common Problems with free
-1. Free the same block of memory more than one time: double freeing
-2. Free something that is not at the start of the block return by malloc
-3. Free a variable that is not on the heap
-When we request for 4 places, for example, the malloc gives us 8, the first four is the information of this allocation, and the last four is your data.
10. realloc
-If we need more than what we wanted before, we should use realloc.
void * realloc (void * ptr, size_t size);
void* means the same return type as malloc; location of new memory
ptr means the pointer to the original memory allocated via malloc
size is the new size request
-realloc effectively resizes a malloc region of memory.
-Same as malloc, if fail, return NULL, if success, return the address
-It doesn't have to be near the original location in the heap
-It will create a new address with new length, and then copy original values to it and then free original values.
11. getline
-We can use getline to read a string of any length and allocate memory that lasts after the function returns.
ssize_t getline (char ** linep,
size_t * linecapp,
FILE * stream);
- Here size_t returns the number of characters written(counting the '\n', not counting '\0') or -1 if an error occurs.
- char ** linep means the pointer to a malloced buffer where the line will be written to (or NULL if getline should perform malloc)
- size_t * linecapp means the pointer to the size of the malloced buffer
- FILE * stream is the pointer to the file to be read
- It will use linep if it is not NULL, to start with. But the buffer is not long enough, getline realloc the buffer as needed.
-If linep is NULL, getline malloc a new buffer.
-getline function returns -1 on an error (including end of file) and the number of bytes read on success.
-return type is ssize_t, which stands for "signed size_t" - that is, the signed integer type, which has the same number of bytes as size_t (so it can return -1)
summary& understanding after reading <<All of Programming>> chapter 12
Comments
Post a Comment