{"id":5242,"date":"2022-03-12T00:01:50","date_gmt":"2022-03-12T08:01:50","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5242"},"modified":"2022-03-19T08:03:11","modified_gmt":"2022-03-19T15:03:11","slug":"the-perils-of-the-memset-function","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5242","title":{"rendered":"The Perils of the <em>memset()<\/em> Function"},"content":{"rendered":"<p>While researching the upcoming &mdash; and significant &mdash; C23 version of the C programming language, I learned something surprising: The <em>memset()<\/em> function will be deprecated. It effectively does nothing when used in the C23 standard. The reason makes a lot of sense.<br \/>\n<!--more--><br \/>\nI wrote about the <em>memset()<\/em> function in a<a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4728\"> Lesson from 2021<\/a>. What it does is to initialize a chunk of memory (a buffer) to a specific value. Here is the <em>man<\/em> page format:<\/p>\n<p><code>void *memset(void *b, int c, size_t len);<\/code><\/p>\n<p>Defined in the <code>string.h<\/code> header file, the <em>memset()<\/em> function writes <code>len<\/code> bytes of value <code>c<\/code> to the buffer at <code>b<\/code>. As I wrote last year, <em>memset()<\/em> initializes a buffer, ensuring that its contents are zero or whatever value you set. Even so, this function is burdened with a number of issues.<\/p>\n<p>First, no guarantee is available to prove that buffer <code>b<\/code> is <code>len<\/code> bytes in size. So the function could overwrite memory if you&#8217;re not careful.<\/p>\n<p>Second, compiler optimization often nullifies the function, rending the buffer uninitialized. This optimization happens all the time, so unless you disable it or go to the effort to confirm that the program actually writes data to the entire buffer, who knows whether the buffer is initialized?<\/p>\n<p>One of the major issues here is that network programming often uses the <em>memset()<\/em> function to zero out important structures. If such a structure isn&#8217;t &#8220;zeroed out,&#8221; network functions behave improperly.<\/p>\n<p>An alternative, secure version of the function is available, <em>memset_s()<\/em>. Also defined in the <code>string.h<\/code> header, this function isn&#8217;t part of the standard C library. Here is the <em>man<\/em> page format:<\/p>\n<p><code>errno_t memset_s(void *s, rsize_t smax, int c, rsize_t n);<\/code><\/p>\n<p>Argument <code>s<\/code> is the buffer to overwrite and <code>smax<\/code> is the buffer&#8217;s size. Argument <code>c<\/code> is the character (<em>unsigned char<\/em>) to write, <code>n<\/code> is the number of characters, which must be less than <code>smax<\/code>. The function returns zero upon success, otherwise an error code is returned as defined in its <em>man<\/em> page. The error code is not an <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=1735\"><em>errno<\/em> value<\/a>. Unlike the <em>memset()<\/em> function, <em>memset_s()<\/em> isn&#8217;t optimized by the compiler.<\/p>\n<p>Here is an update to the code I wrote last year to test the <em>memset()<\/em> function, but using <em>memset_s()<\/em> instead.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_03_12-Lesson.c\" rel=\"noopener\" target=\"_blank\">2022_03_12-Lesson.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;string.h&gt;\r\n\r\nint main()\r\n{\r\n    char buffer[BUFSIZ];\r\n\r\n    memset_s(buffer, BUFSIZ, '\\0', BUFSIZ);\r\n    puts(\"Buffer initialized\");\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The two changes required are first, of course, to change <em>memset()<\/em> to <em>memset_s()<\/em>. The second change is to add the function&#8217;s second argument, the buffer size. In this code I use <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=4711\">the <code>BUFSIZ<\/code> constant<\/a>, which appears as both the second and fourth arguments.<\/p>\n<p>Here is the boring sample run:<\/p>\n<p><code>Buffer initialized<\/code><\/p>\n<p>In my older post, I also mentioned the <em>bzero()<\/em> function, which works like <em>memset()<\/em> but always uses the zero value to fill the buffer. The problem with <em>bzero()<\/em> is that it&#8217;s non-standard. As I wrote in the original post, it&#8217;s still okay to write your own function to initialize a chunk of memory. Especially if your compiler lacks the <em>memset_s()<\/em> function, this is the route I would recommend taking.<\/p>\n<p>In <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5248\">next week&#8217;s Lesson<\/a>, I cover the manual method to initialize a structure to zero.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Turns out that this common function could be a security risk. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5242\">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-5242","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\/5242","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=5242"}],"version-history":[{"count":5,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5242\/revisions"}],"predecessor-version":[{"id":5263,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5242\/revisions\/5263"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5242"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5242"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5242"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}