1 / 5

C and Memory

How variables in typical implementations of C look in memory (32-bit). 1) Variable Declarations. C and Memory. 2) Function Parameters. 3) Dynamic Allocation. 4) Multi-level Pointers. Ratanak Lun Temple University Fall 2008. Character array ‘arr’ of size 3 is declared.

tamma
Download Presentation

C and Memory

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. How variables in typical implementations of C look in memory (32-bit). 1) Variable Declarations C and Memory 2) Function Parameters 3) Dynamic Allocation 4) Multi-level Pointers RatanakLun Temple University Fall 2008

  2. Character array ‘arr’ of size 3 is declared. (‘arr’ can be treated like a pointer whose value is its own address: 14) main() function stack is removed. Return value: 0. main() will return 0. Character ‘b’ is declared. Integer ‘a’ is declared. main() function stack is created. Integer ‘i’ is declared. Process stack is removed. Process stack is created. Integer ‘j’ is declared and assigned value: 10. Click to step through code. Source: // Global declarations inti; int j = 10; // Main entry point int main(void) { int a; char b; char arr[3]; return 0; } System Memory (Address: 1) Process Memory (Address: 1) Return Value: 0 [1] Address: 15 Value: ??? [0] Address: 14 Value: ??? char b Address: 13 Value: ??? int a Address: 9-12 Value: ??? int j Address: 5-8 Value: 10 int i Address: 1-4 Value: ??? [2] Address: 16 Value: ??? int main(void) (Address: 9) Variable Declarations char[3] arr Address: 14-16 Value: 14 Heap (Start Address: 100) Note: For simplicity, memory is assumed to only contain variables and allocated data.

  3. Character array ‘str’ is declared and assigned string “sun”. (‘str’ can be treated like a pointer whose value is its own address: 9) main() function stack is removed. Return value: 0. someFunc() function stack is removed. Return value: 13. someFunc() is called with the arguments: value of ‘i’ (10) and value of ‘str’ (9). A value has been written to an invalid memory address. Subsequent declarations and function calls can overwrite it! Value of ‘j’ is deferenced to address 13. Address 13 is assigned value: 50. Process stack is removed. Process stack is created. main() will return 0. ‘j’ now points to an address not on the stack. ‘j’ is assigned the return value of someFunc(): 13. someFunc() will return address of ‘byVal’ (13). Address 11 is assigned value: ‘m’. Value of ‘byVal’ is incremented by 1. someFunc() function stack is created. Character pointer ‘byRef’ is declared and assigned value: 9. Integer ‘byVal’ is declared and assigned value: 10. Integer ‘i’ is declared and is assigned value: 10. Slot 2 of the array pointed to by ‘byRef’ has address 11. Integer pointer ‘j’ is declared. main() function stack is created. Click to step through code. Source: int* someFunc(intbyVal, char* byRef) { byVal++; byRef[2] = ‘m’; return &byVal; // Don’t do this! It’s local! } int main(void) { inti = 10; int *j; char str[4] = {‘s’, ‘u’, ‘n’, ‘\0’}; // ‘\0’ is the string null terminator j = someFunc(i, str); (*j) = 50; // No! The address is invalid! return 0; } System Memory (Address: 1) Process Memory (Address: 1) Return Value: 13 Return Value: 0 char[4] str Address: 9-12 Value: 9 int byVal Address: 13-16 Value: 11 ??? Address: 13 Value: 50 int byVal Address: 13-16 Value: 10 ??? Address: 13 Value: ??? int* j Address: 5-8 Value: ??? int* j Address: 5-8 Value: 13 char* byRef Address: 17-20 Value: 9 [3] Address: 12 Value: ‘\0’ [0] Address: 9 Value: ‘s’ [2] Address: 11 Value: ‘n’ int i Address: 1-4 Value: 10 [1] Address: 10 Value: ‘u’ [2] Address: 11 Value: ‘m’ int main(void) (Address: 1) Function Parameters int* someFunc(int byVal=10, char* byRef=9) (Address: 13) Heap (Start Address: 100) Note: For simplicity, memory is assumed to only contain variables and allocated data.

  4. malloc() allocates space on the heap for 1 byte at address 101. (Address 100 might not be reused immediately.) free() is called with the argument: the value of ‘ptr’ (100). Unreferenced allocated memory is left for someone else to clean up. How rude! malloc() stack is removed. Return value: 101. Address 101 unreferenced. Memory leak! malloc() stack is removed. Return value: 100. Character array ‘a’ is declared and each slot is assigned a value. (‘a’ can be treated like a pointer whose value is its own address: 1) malloc() is called with the argument: the value of ‘sizeof(char)’ (1). Value of ‘ptr’ is dereferenced to address 100 and then address 100 is assigned value: ‘o’. malloc() allocates space on the heap for 1 byte at address 100. main() function stack is removed. Return value: 0. Return value 100 is assigned to ‘ptr’. free() stack is removed. NOTE: ‘ptr’ is now pointing at an unallocated address. Integer ‘size’ is declared and assigned value: 1. Void pointer ‘p’ is declared and assigned value: 100. Return value 101 is assigned to ‘ptr’. main() will return 0. Process stack is removed and… main() function stack is created. Character pointer ‘ptr’ is declared. free() function stack is created. Slot 2 of the array pointed to by ‘ptr’ has address 3. Process stack is created. free() uses value of ‘p’(100) as the address to deallocate. malloc() function stack is created. Address 3 is assigned value: ‘m’. ‘ptr’ is assigned the value of ‘a’ (1). Click to step through code. Source: int main(void) { char a[3] = {‘s’, ‘u’, ‘n’}; // not a string! // A string is a series of characters // terminated by a null byte (‘\0’) char *ptr; ptr = malloc(sizeof(char)); (*ptr) = ‘o’; free(ptr); ptr = malloc(sizeof(char)); ptr = a; // memory leak ptr[2] = ‘m’; return 0; } System Memory (Address: 1) Process Memory (Address: 1) Return Value: 0 Return Value: 101 Return Value: 100 int size Address: 8-11 Value: 1 void* p Address: 8-11 Value: 100 char* ptr Address: 4-7 Value: 1 ??? Address: 100 Value: ??? char* ptr Address: 4-7 Value: ??? [1] Address: 2 Value: ‘u’ [2] Address: 3 Value: ‘n’ char Address: 100 Value: ??? char Address: 100 Value: ‘o’ [2] Address: 3 Value: ‘m’ char* ptr Address: 4-7 Value: 100 char Address: 101 Value: ??? char* ptr Address: 4-7 Value: 101 [0] Address: 1 Value: ‘s’ char[3] a Address: 1-3 Value: 1 int main(void) (Address: 1) Dynamic Allocation void* malloc(int size=1) (Address: 8) void free(void* p=100) (Address: 8) Heap (Start Address: 100) Unreferenced  Note: For simplicity, memory is assumed to only contain variables and allocated data.

  5. NewProduct() removed from the stack. Return value: 0. ‘r’ is checked to see if NewProduct() was successful. r == 0? True. free() is called with argument: value of ‘a’: 100 Value of ‘out’ dereferences to address 5. Address 5 is assigned value of ‘tmp’: 100 Pointer to Product pointer ‘out’ declared and assigned value: 5 NewProduct() is called with arguments: integer 1, integer 3, and address of ‘a’ (5) A memory block the size of a Product object is malloc()’d. Address: 100 ‘tmp’ is checked to see if malloc() failed. 100 == NULL? False. ‘id’ member of object pointed to by ‘tmp’ is assigned the value of ‘i’: 1 ‘price’ member of object pointed to by ‘tmp’ is assigned the value of ‘p’: 3 main() function stack is removed. Return value: 0. main() will return 0. Return value 0 is assigned to ‘r’. Address 100 is deallocated. Process stack is created. Process stack is removed. main() function stack is created. NewProduct() stack is created. ‘a’ now has value 100 (points to address 100). Integer ‘i’ declared and assigned value: 1 Product pointer ‘tmp’ declared. Product pointer ‘a’ declared. Address 100 is assigned to Product pointer ‘tmp’. Integer ‘r’ declared. Integer ‘p’ declared and assigned value: 3 NewProduct() will return 0. Click to step through code. Source: typedefstruct { int id; intprice; } Product; intNewProduct(inti, intp, Product ** out) { Product * tmp; tmp = malloc(sizeof(Product)); if(tmp == NULL) { return -1; } tmp->id = i; tmp->price = p; (*out) = tmp; return 0; } int main(void) { int r; Product * a; r = NewProduct(1, 3, &a); if(r == 0) free(a); // destroy product return 0; } System Memory (Address: 1) Process Memory (Address: 1) Return Value: 0 Return Value: 0 int r Address: 1-4 Value: ??? Product* a Address: 5-8 Value: 100 int i Address: 9-12 Value: 1 Product* a Address: 5-8 Value: ??? int r Address: 1-4 Value: 0 Product Address: 100-107 int p Address: 13-16 Value: 3 Product** out Address: 17-20 Value: 5 Product* tmp Address: 21-24 Value: 100 Product* tmp Address: 21-24 Value: ??? int main(void) (Address: 1) Multi-level Pointers Int NewProduct(int i=1, int p=3, Product** out=5) (Address: 9) Heap (Start Address: 100) int price Address: 104-107 Value: ??? int price Address: 104-107 Value: 3 int id Address: 100-103 Value: ??? int id Address: 100-103 Value: 1 Note: For simplicity, memory is assumed to only contain variables and allocated data.

More Related