{"id":5248,"date":"2022-03-19T00:01:38","date_gmt":"2022-03-19T07:01:38","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5248"},"modified":"2022-03-12T10:13:40","modified_gmt":"2022-03-12T18:13:40","slug":"initializing-a-buffer-your-own-memset-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5248","title":{"rendered":"Initializing a Buffer &#8211; Your Own <em>memset()<\/em> Function"},"content":{"rendered":"<p>As I wrote in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5242\">last week&#8217;s Lesson<\/a>, the C23 standard renders the <em>memset()<\/em> function &mdash; a standard C library function for over 30 years &mdash; obsolete. If you want to initialize a buffer, you can use the secure <em>memset_s()<\/em> or just initialize the buffer manually or with your own <em>memset()<\/em>-like function.<br \/>\n<!--more--><br \/>\nAlas, the parade of safe C functions isn&#8217;t widely supported. Each of these functions shares a name with their &#8220;unsafe&#8221; (or easily abused) counterparts, but with the <em>_s<\/em> suffix. This rule is true for <em>memset()<\/em>, where the safe version is named <em>memset_s()<\/em>. Because these safe functions are inconsistently implemented, a definitive method to detect their inclusion with any compiler isn&#8217;t available. So if you want to use a safer version of <em>memset()<\/em>, and <em>memset_s()<\/em> isn&#8217;t available to your compiler, you must code your own or just manually initialize a buffer.<\/p>\n<p>The following code zeroes out the <code>human<\/code> structure variable <code>my<\/code>:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_03_19-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2022_03_19-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    struct human {\r\n        char name[32];\r\n        int age;\r\n        float weight;\r\n    } my;\r\n    int x;\r\n\r\n    for( x=0; x&lt;32; x++)\r\n        my.name[x] = '\\0';\r\n    my.age = 0;\r\n    my.weight = 0.0;\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>for<\/em> loop at Line 12 initializes all 32 elements of the name array member to the null character, <code>\\0<\/code>. Lines 14 and 15 set the other two structure members to zero. This process effectively initializes the buffer, removing whatever garbage already exists in memory.<\/p>\n<p>The program has no output, though I ran it through the Code::Blocks debugger to watch as the relevant memory chunk was cleared. Figure 1 illustrates the before (above) and after (below) effect of clearing the structure&#8217;s memory.<\/p>\n<div id=\"attachment_5252\" style=\"width: 558px\" class=\"wp-caption aligncenter\"><img loading=\"lazy\" decoding=\"async\" aria-describedby=\"caption-attachment-5252\" src=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2022\/03\/0319-figure1.png\" alt=\"\" width=\"548\" height=\"291\" class=\"size-full wp-image-5252\" srcset=\"https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2022\/03\/0319-figure1.png 548w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2022\/03\/0319-figure1-300x159.png 300w, https:\/\/c-for-dummies.com\/blog\/wp-content\/uploads\/2022\/03\/0319-figure1-500x266.png 500w\" sizes=\"auto, (max-width: 548px) 100vw, 548px\" \/><p id=\"caption-attachment-5252\" class=\"wp-caption-text\">Figure 1. A memory dump from the Code::Blocks debugger, showing before (above) and after( below).<\/p><\/div>\n<p>The problem with this approach is that it&#8217;s specific to one type of structure. A better approach is to zero out memory as a buffer &mdash; the entire thing &mdash; regardless of its specific data type contents. This approach is used in the following code update:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_03_19-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2022_03_19-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nint main()\r\n{\r\n    struct human {\r\n        char name[32];\r\n        int age;\r\n        float weight;\r\n    } my;\r\n    int x;\r\n    char *b;\r\n\r\n    b = (char *)&amp;my;\r\n    for( x=0; x&lt;sizeof(struct human); x++)\r\n        *(b+x) = 0;\r\n\r\n    return(0);\r\n}<\/pre>\n<p>This code adds <em>char<\/em> pointer <code>b<\/code>. Its value is set to the address of <code>human<\/code> <em>struct<\/em> variable <code>my<\/code> at Line 13, which is typecast as a <em>char<\/em> pointer. Remember that in C, a <em>char<\/em> is sorta kinda the same as a byte. The <em>for<\/em> loop then initializes the entire structure&#8217;s contents to zero, using the <em>sizeof<\/em> operator to return the structure&#8217;s size in memory.<\/p>\n<p>Of course, it would be better to put the zeroing code into a function, as is done here:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_03_19-Lesson-c.c\" rel=\"noopener\" target=\"_blank\">2022_03_19-Lesson-c.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nvoid memzero(void *b, int len)\r\n{\r\n    int x;\r\n    char *a;\r\n\r\n    a = (char *)b;\r\n    for( x=0; x&lt;len; x++)\r\n        *(a+x) = 0;\r\n}\r\n\r\nint main()\r\n{\r\n    struct human {\r\n        char name[32];\r\n        int age;\r\n        float weight;\r\n    } my;\r\n\r\n    memzero(&amp;my,sizeof(struct human));\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>memzero()<\/em> function has a <em>void<\/em> pointer as its first argument and the buffer size as its second. The <em>void<\/em> data type allows any pointer to be passed, such as the address of <code>human<\/code> structure <code>my<\/code> at Line 21. The structure, not being a pointer itself, is prefixed with the &amp;, address-of operator.<\/p>\n<p>Within the <em>memzero()<\/em> function, the <em>void<\/em> pointer <code>b<\/code> is assigned to <em>char<\/em> pointer <code>a<\/code> for processing. The result is the same: The buffer is initialized to zero. So this function works as a replacement for <em>memset()<\/em>, but it&#8217;s still subject to compiler optimization.<\/p>\n<p>To disable compiler optimization, use the command line switch <code>-O0<\/code> (capital O, zero). This switch is the default, so it may not have any effect on your code.<\/p>\n<p>A better approach is to classify <em>int<\/em> variable <code>x<\/code> as <em>volatile<\/em> at Line 5:<\/p>\n<p><code>volatile int x;<\/code><\/p>\n<p>The <em>volatile<\/em> qualifier directs the compiler not to mess with variable <code>x<\/code>, which should ensure that the loop is processed completely and not optimized in any way. Better than using this trick is to find a compiler that supports the <em>memset_s()<\/em> function, or just wait until the C23 release becomes standard.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>The <em>memset()<\/em> function is deemed insecure, so why not code your own version?  <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5248\">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-5248","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\/5248","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=5248"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5248\/revisions"}],"predecessor-version":[{"id":5258,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5248\/revisions\/5258"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5248"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5248"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5248"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}