1 / 20

Dynamic Memory Allocation

Dynamic Memory Allocation. Suppose we defined the data type:. struct custrec { char ssn[10]; char name[31]; };. (Which requires 41-bytes of contiguous RAM). And then we were to make the declaration:. struct custrecrec customer[1000];.

saniya
Télécharger la présentation

Dynamic Memory Allocation

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. Dynamic Memory Allocation Suppose we defined the data type: struct custrec { char ssn[10]; char name[31]; }; (Which requires 41-bytes of contiguous RAM) And then we were to make the declaration: struct custrecrec customer[1000]; (Which requires 41 * 1,000 = 41,000 bytes of contiguous RAM) We might get the run-time error message: Not enough memory (Or something similar)

  2. 401KB: Assigned 36 KB Available 43 KB: Assigned 28 KB: Avail. 78 KB: Assigned 22 KB: Avail. 32 KB: Assigned 29 KB: Available 31 KB: Avail. 234 KB: Assigned 512 KB: Assigned 12 KB: Avail. 76 KB: Assigned 18 KB: Avail. 35 KB: Avail. 386 KB: Assigned 26 KB: Avail. 127 KB: Assigned 14 KB: Avail. 23 KB: Assigned 30 KB: Avail. Well, That’s because there is not enough memory, Right??? Not necessarily. If we were to check, we might find that we actually have 250,000 bytes of ram available. Why Can’t we get the memory we need ?? If we were to look inside RAM, we might see:

  3. 65100 - 65109 65110 - 65140 65141 - 65145 ssn name next To get the necessary memory we need NON-CONTIGUOUS storage. Let’s redefine our data type: struct custrec { char ssn[10]; char name[31]; struct custrec * next; }; (Which requires 45-bytes of contiguous RAM) How can we have a pointer within a structured object ?? Remember, when we defined a structured data object (struct), we noted that it could also include a pointer: • The variable (location in RAM) next will contain an address. If we go that address (assume next contains the address 65100), we will find (on 45-bytes): Character array on 10-bytes Character array on 31-bytes Address Field on 4-bytes

  4. ssn name 9622 - 9774 9322 - 9417 9254 - 9302 9544 - 9598 ‘123456789’ ‘234567890’ ‘345678901’ ‘456789012’ ‘567890123’ ‘Chaucer, G.’ ‘Milton, J.’ ‘Browning, R.’ ‘Eliot, T.S.’ ‘Shelley, P.’ Available Available Available Available 9200 - 9253 9404 - 9543 9303 - 9321 9599 - 9621 Assigned Assigned Assigned Assigned How would this work ??? Assume that we wished to keep track of the following records: But if we were to look at available RAM we saw:

  5. We know that our structured data object requires: struct custrec { char ssn[10]; 10-bytes char name[31]; }; 31-bytes 41-bytes of contiguous storage OR: 41 * 5 = 205-bytes of contiguous storage for the database IF we look at our available storage, however: Available Locations Contiguous RAM Available 9254 - 9302 49 9322 - 9417 96 9544 - 9598 55 9622 - 9774 153 353 Total Bytes Which is enough for our entire database, and even 1, 2, or 3 records contiguously, BUT NOT ALL 5 RECORDS CONTIGUOUSLY

  6. 9254 - 9263 9264 - 9294 9295 - 9298 “123456789” “Chaucer, G.” 9322 9322- 9331 9332 - 9360 9361- 9364 “234567890” “Milton, J.” 9365 9365 - 9374 9375 - 9405 9406 - 9409 “345678901” “Browning R.” 9544 9544 - 9553 9554 - 9584 9585 - 9588 9622 - 9631 9632 - 9662 9663 - 9666 “456789012” “Eliot, T.S.” 9622 “567890123” “Shelley, P.” NULL Now, let’s redefine our data type as we did before: struct custrec { char ssn[10]; 10-bytes char name[31]; 31-bytes struct custrec * next; }; 4-bytes 45 bytes of contiguous storage We could set-up a linked-list to take advantage of our limitations:

  7. NOTE: 1. We still need to allocate 45-contiguous bytes (the size of our record). 2. Records may be allocated contiguously (as with records 3 and 4) but need not be. If contiguous bytes are available, they will be allocated. If not, the next (available) grouping of 45-bytes will be allocated. 3. The space will be Allocated at RUN-TIME; NOT before Does that mean that we must request 45-bytes of contiguous storage 5 times (once for each record) ??? YES ! How do we request the needed memory ?? In C, the necessary statement is: newcust = (struct custrec *) malloc(sizeof(struct custrec)); Assuming that we had previously made the declaration: struct custrec * newcust;

  8. Command Explanation: struct custrec * newcust; Sets aside 4-bytes of storage at location newcust. newcust = (struct custrec *) malloc(sizeof(struct custrec)); Return the number of bytes we need (in our case: 45) newcust = (struct custrec *) malloc(sizeof(struct custrec)); Function malloc (found in stdlib.h) takes one argument (the number of contiguous bytes of RAM we need) and returns the the address of where those contiguous bytes can be found.

  9. newcust = (struct custrec *) malloc(sizeof(struct custrec)); REMEMBER: When we refer to an address, we MUST know what type of data is stored there (in our case, the data type struct custrec). • We need to specify the data type which will be found at that address in advance newcust = (struct custrec *) malloc(sizeof(struct custrec)); Store the address at which 45-bytes of contiguous (where the data type struct custrec can be found) at location (variable) newcust. What if there is NOT enough contiguous RAM available ??

  10. A good programmer will always check: newcust = (struct custrec *) malloc(sizeof(struct custrec)); if (newcust == NULL) // is there enough memory? { puts("Memory allocation failed - Bye!"); return(0); } Function malloc will return the value NULL if the requested amount of contiguous RAM could not be found What about the C code necessary ?? The code that follows assumes that: 1. The database will be entered from the keyboard 2. The User will continue entering records until they enter a RETURN for the customer’s name

  11. #include <stdio.h> #include <stdlib.h> #include <string.h> struct custrec { char ssn[10], name[31]; struct custrec * next; }; int main() { struct custrec *newcust, *first, *previous, *present; int numrecs = 0; do { newcust = (struct custrec *) malloc(sizeof(struct custrec)); if (newcust == NULL) { puts("memory allocation failed - bye!"); return 0; } if (numrecs == 0) first = newcust; else previous->next = newcust; newcust->next = NULL; numrecs++; printf("Enter Name for customer %d (Return to Quit): ",numrecs); gets(newcust->name); if (strlen(newcust->name)>0) { printf("Enter SSN for customer %s: ",newcust->name); gets(newcust->ssn); } previous = newcust; } while (strlen(newcust->name)>0); return 0; }

  12. 9254 - 9263 9264 - 9294 9295 - 9298 “123456789” “Chaucer, G.” 9322 9322- 9331 9332 - 9360 9361- 9364 “234567890” “Milton, J.” 9365 9365 - 9374 9375 - 9405 9406 - 9409 “345678901” “Browning R.” 9544 9544 - 9553 9554 - 9584 9585 - 9588 9622 - 9631 9632 - 9662 9663 - 9666 “456789012” “Eliot, T.S.” 9622 “567890123” “Shelley, P.” NULL There is one additional feature to dynamically allocated lists: We can free-up memory which we no longer require Assume we had set up our list (as before): And we now wished to eliminate Eliot from the list

  13. How?? The procedure is relatively simple: 1. Get the address of the record to be deleted (assume we store the address in location newcust). 2. Rearrange the pointers: a. If the first record, make the next record the first record b. If the last record, make the previous record the last one c. Otherwise, have the previous record point to the next record 3. Free the address stored (at location newcust). The C command necessary ??? Assuming we have already stored the address to be freed at location newcust, all we need to do is issue the command: free(newcust);

  14. How is this different than re-arranging the pointers as we did with simple linked lists ?? Unlike our previous examples, the space allocated for the record (in our example, locations 9544 to 9588) are now available for reuse.

More Related