{"id":6534,"date":"2024-08-24T00:01:17","date_gmt":"2024-08-24T07:01:17","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=6534"},"modified":"2024-08-17T12:17:40","modified_gmt":"2024-08-17T19:17:40","slug":"exploring-allocated-memory","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=6534","title":{"rendered":"Exploring Allocated Memory"},"content":{"rendered":"<p>Details about a pointer can easily be obtained and output: it&#8217;s name, address, and contents. Obtaining the size of the buffer it references, however, is a different animal.<br \/>\n<!--more--><br \/>\nIn C, it&#8217;s up to the programmer to know the size of an allocated memory chunk. This value must be managed and adhered to lest the program do something ugly.<\/p>\n<p>But how does the computer know the size? How does the <em>realloc()<\/em> function know how much memory to release or where to add memory?<\/p>\n<p>While it&#8217;s up the C programmer to know these values, internally there must be a way to find out how much memory is associated with a pointer. One function available is <em>malloc_usable_size()<\/em>, prototyped in the <code>malloc.h<\/code> header file. Here&#8217;s the <em>man<\/em> page format:<\/p>\n<p><code>size_t malloc_usable_size (void *ptr);<\/code><\/p>\n<p>The function&#8217;s argument is a pointer. The value returned is a <em>size_t<\/em>, representing the number of bytes available at the address saved in pointer <code>ptr<\/code>.<\/p>\n<p>This function isn&#8217;t without its quirks. First, it&#8217;s a GNU extension and not part of the standard C library. Second, the value returned is intended for research and debugging purposes. Because this is my goal, it&#8217;s why I choose to use this function.<\/p>\n<p>The following program is an update from <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6528\">last week&#8217;s Lesson<\/a>. I added a series of <em>printf()<\/em> statements to output values associated with the original buffer, the allocated buffer, and then re-allocated buffer.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2024_08_24-Lesson.c\" rel=\"noopener\" target=\"_blank\">2024_08_24-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n#include &lt;string.h&gt;\r\n#include &lt;malloc.h&gt;\r\n\r\nint main()\r\n{\r\n    char string[] = \"Hello there!\";\r\n    char *sp;\r\n\r\n    printf(\"Original string: %s\\n\",string);\r\n    printf(\"Original string's address: %p\\n\",string);\r\n    printf(\"Original string's size: %zu\\n\",sizeof(string));\r\n\r\n    <span class=\"comments\">\/* allocate way too much storage *\/<\/span>\r\n    sp = malloc(2048);\r\n    if( sp==NULL )\r\n    {\r\n        fprintf(stderr,\"Failed to allocate way too much storage\\n\");\r\n        exit(1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* copy the string into storage *\/<\/span>\r\n    strcpy(sp,string);\r\n    printf(\"String copied: '%s'\\n\",sp);\r\n    printf(\"New storage address: %p\\n\",sp);\r\n    printf(\"New storage size: %zu\\n\",malloc_usable_size(sp));\r\n\r\n    <span class=\"comments\">\/* reallocate (re-size) the storage *\/<\/span>\r\n    sp = realloc(sp,strlen(string)+1);\r\n    if( sp==NULL )\r\n    {\r\n        fprintf(stderr,\"Failed to reallocate storage\\n\");\r\n        exit(1);\r\n    }\r\n    printf(\"Storage reallocated: '%s'\\n\",sp);\r\n    printf(\"Reallocated address: %p\\n\",sp);\r\n    printf(\"Reallocated address size: %zu\\n\",malloc_usable_size(sp));\r\n\r\n    <span class=\"comments\">\/* clean up *\/<\/span>\r\n    free(sp);\r\n    return(0);\r\n}<\/pre>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>Original string: Hello there!<br \/>\nOriginal string's address: 0x7ffed53ba57f<br \/>\nOriginal string's size: 13<br \/>\nString copied: 'Hello there!'<br \/>\nNew storage address: 0x5621ee48a6b0<br \/>\nNew storage size: 2056<br \/>\nStorage reallocated: 'Hello there!'<br \/>\nReallocated address: 0x5621ee48a6b0<br \/>\nReallocated address size: 24<\/code><\/p>\n<p>The <code>%p<\/code> placeholder is used to obtain the original array&#8217;s address. You can prefix the name with an <code>&<\/code> (address-of) operator or not; the result is the same. The <em>sizeof<\/em> operator easily obtains the value of the original string, which is an array.<\/p>\n<p>When <em>malloc()<\/em> allocates 2048 bytes of storage, its address is returned and the size. The <code>%zu<\/code> placeholder represents a <em>size_t<\/em> value in a <em>printf()<\/em> format string.<\/p>\n<p>The <em>size_t<\/em> value returned is 2056, eight bytes larger than what&#8217;s allocated. This result is typical for the <em>malloc_usable_size()<\/em> function. The eight extra bytes are most likely processor overhead or used for memory alignment. This extra storage shouldn&#8217;t be accessed or used.<\/p>\n<p>When the <em>realloc()<\/em> function reallocates storage, the original memory address is retained. The new buffer size reported by <em>malloc_usable_size()<\/em> is the actual size allocated. Again, this value is for diagnostic and debugging purposes.<\/p>\n<p>I tried to come up with my own version of the <em>realloc()<\/em> function, but I can&#8217;t duplicate whatever magic it performs. So I can just be thankful that it exists and use it as necessary.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Time to look under the hood at what the <em>malloc()<\/em> and <em>realloc()<\/em> functions do. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=6534\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[2],"tags":[],"class_list":["post-6534","post","type-post","status-publish","format-standard","hentry","category-main"],"_links":{"self":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6534","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=6534"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6534\/revisions"}],"predecessor-version":[{"id":6539,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/6534\/revisions\/6539"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=6534"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=6534"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=6534"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}