1 / 20

ECE 103 Engineering Programming Chapter 47 Dynamic Memory Alocation

ECE 103 Engineering Programming Chapter 47 Dynamic Memory Alocation. Herbert G. Mayer, PSU CS Status 6/4/2014 Initial content copied verbatim from ECE 103 material developed by Professor Phillip Wong @ PSU ECE. Syllabus. Memory Allocation Functions Creating a 1-D Array at Runtime

Download Presentation

ECE 103 Engineering Programming Chapter 47 Dynamic Memory Alocation

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. ECE 103 Engineering ProgrammingChapter 47Dynamic Memory Alocation Herbert G. Mayer, PSU CS Status 6/4/2014 Initial content copied verbatim from ECE 103 material developed by Professor Phillip Wong @ PSU ECE

  2. Syllabus • Memory Allocation Functions • Creating a 1-D Array at Runtime • Creating a 2-D Array at Runtime • calloc, malloc, free • Dangers

  3. Memory Allocation Functions The size of arrays must be known at compile-time (C90 limitation only; C99 supports VLAs). A C program can also make a request at runtime for a memory block of arbitrary size. If the memory block is no longer needed, the system can be told to release the memory. To use C’s memory allocation functions, add #include <stdlib.h> to the source file. 2

  4. calloc void * calloc (size_t N, size_tbsize); Allocates a block of memory from the heap at runtime to use for data storage. Block can contain N items, each of size bsize. Block is initialized to zero. If successful, returns a pointer to the allocated memory. If unsuccessful, returns the NULL value. Storage persists until explicitly freed or the program terminates. Example: Create a block of storage for 512 integers at runtime. int *p; p = (int*) calloc(512, sizeof(int)); 3

  5. malloc void * malloc (size_tbsize); Allocates a block of memory from the heap at runtime to use for data storage. Block is of size bsize. Block is not initializedto zero (i.e., indeterminate values). If successful, returns a pointer to the allocated memory. If unsuccessful, returns the NULL value. Storage persists until explicitly freed or the program terminates. Example: Create a 1024 character memory block at runtime. char *q; q = (char *) malloc(1024 * sizeof(char)); 4

  6. realloc void * realloc (void *p, size_tbsize); Changes the size of a previously allocated memory block. p is a pointer to the existing block. bsize is the desired new size. If successful, returns a pointer to the resized block. If unsuccessful, returns the NULL value. Example: Suppose p points to a 1024 char block created by malloc. Change the block’s size to 2048. p_new= (char *) realloc(p, 2048*sizeof(char)); 5

  7. free void * free (void *p); Releases memory that has been previously allocated by calloc, malloc, or reallocback to the heap. p is a pointer to the existing block. If p is NULL, then free does nothing. Example: Suppose p points to a dynamically allocated memory block. The storage is no longer needed, so free up the memory. free(p); 6

  8. Potential Dangers … Dynamically allocated memory exists until it is released by free, or until the program terminates. If a pointer “loses track” of a memory block, and there are no other pointers still tracking that block, then the block becomes inaccessible. Inaccessible blocks still continue to use memory for as long as the program is running (memory leak). 7

  9. mem… void * memset (void *ptr, int value, size_t num); Sets first num bytes of the memory block pointed by ptr to the specified value. void * memcpy (void *dst, const void *src, size_t num); Copies the values of num bytes from the location pointed by src to the memory block pointed by dst. No overlap is allowed. Returns dst. void * memmove (void *dst, const void *src, size_t num); Copies the values of num bytes from the location pointed by src to the memory block pointed by dst. Overlap is allowed. Returns dst. int memcmp (const void *ptr1, const void *ptr2, size_t num); Compares the first num bytes of the memory block pointed by ptr1 to the first num bytes pointed by ptr2. Returns zero if equal, or non-zero otherwise. void * memchr (const void *ptr, int value, size_t num); Searches within the first num bytes of the memory block pointed by ptr for the first occurrence of value. If found, returns pointer to location, or NULL otherwise. 8

  10. Creating a 1-D Array at Runtime When declaring a normal array variable, the size of the array must be specified at compile-time (C90). Using dynamic memory allocation, an array can be created whose size is determined at runtime. The size of the desired block must be passed to either calloc or malloc. The sizeof()operator can determine the block size (in bytes) of a given datatype. 9

  11. The pointer returned by calloc or malloc must be cast to the correct datatype. The pointer should always be tested for NULL! The allocated array can be accessed using array notation. A memory block should be freed when it is no longer needed. 10

  12. Example: Create a 1-D array at runtime that holds up to 10 elements of datatype float. float *A; A = (float *) calloc(10, sizeof(float)); Pointer to the allocated memory block that will hold the 1-D array values. Casts the pointer returned by calloc to the correct datatype Calculates size of datatype(in bytes) Desired 1-D array size Desired datatype 11

  13. Example: #include <stdio.h> #include <stdlib.h> int main (void) { float *A; /* Pointer to 1-D array */ int R; /* Size of the array */ int i; /* Index */ printf("Enter size of the array: "); scanf("%d", &R); /* Create the array at runtime */ if ((A = (float *) calloc(R, sizeof(float))) == NULL) { printf("Error: Could not allocate memory block.\n"); exit(0); } /* Can now access using array notation */ for (i = 0; i < R; i++) A[i] = i; free(A); /* Free up the block */ return 0; } 12

  14. Suppose the entered array size is R = 5 and the system uses 64 bit pointers and 32 bit float values. Assume that calloc returns 2000 as the start address of the allocated memory block. 13

  15. Creating a 2-D Array at Runtime Creating a 1-D array using runtime memory allocation requires a single level of indirection(e.g., double *). To create a 2-D array, two levels of indirection are required (e.g., double **). In other words, a pointer to a pointer is required. 14

  16. The 2-D array is created in two phases: The rows are created first. The return value is a pointer to a pointer. For each row, columns are created. The return value in each case is a pointer. The pointers should always be tested for NULL! The block is released in reverse order, i.e., the columns are freed first and then the rows. 15

  17. Example: Create a 2-D array (size: 5 rows by 3 columns) at runtime that holds elements of type float. float **A; /* Create array of pointers to the rows */ A = (float **) calloc(5, sizeof(float *)); /* Create the rows */ for (i = 0; i < 5; i++) A[i] = (float *) calloc(3, sizeof(float)); Pointer to the allocated row block that contains pointers to the column blocks 16

  18. Example: #include <stdio.h> #include <stdlib.h> int main (void) { float **A; /* Pointer to 2-D array */ int R = 5, C = 3; /* Row and column sizes of the array */ int i, j; /* Row and column indices */ /* Create the rows of the 2-D array */ if ((A = (float **) calloc(R, sizeof(float *))) == NULL) { printf("Error: Cannot allocate memory block.\n"); exit(0); } /* For each row, create the columns */ for (i = 0; i < R; i++) if ((A[i] = (float *) calloc(C, sizeof(float))) == NULL) { printf("Error: Cannot allocate memory block.\n"); exit(0); } /* Can now access using array notation */ for (i = 0; i < R; i++) for (j = 0; j < C; j++) A[i][j] = i+j; for (i = 0; i < R; i++) free(A[i]); /* Free up the columns a row at a time */ free(A); /* Free up the rows */ return 0; } 17

  19. Suppose that R = 5, C = 3 and the system uses 64 bit pointers and 32 bit float values. Assume calloc returns 2000 as the start address of the row block. Suppose that when creating columns, calloc returned 3000, 3012, 3024, 4000, and 4012 for the start addresses of the column blocks. Note: The non-contiguous allocation may be inefficient. Some prefer using a 1-D allocated block and manually calculating 2-D offsets. 18

  20. VLA vs. Dynamic memory allocation What are some pros and cons of using C99’s variable-length arrays versus dynamic memory allocation? + VLAs are easy to define + No pointers to create + Automated memory management (no need to free) − VLAs are stored on the stack →Stack size is limited. Large VLA may overrun space. − Not portable to all compilers C99 19

More Related