{"id":5452,"date":"2022-07-23T00:01:54","date_gmt":"2022-07-23T07:01:54","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=5452"},"modified":"2022-07-16T11:13:00","modified_gmt":"2022-07-16T18:13:00","slug":"returning-a-non-static-string","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=5452","title":{"rendered":"Returning a Non-Static String"},"content":{"rendered":"<p>It&#8217;s possible to return a string created in a function without declaring it <em>static<\/em>. This trick requires some understanding of how functions return values. Nerd alert!<br \/>\n<!--more--><br \/>\nFunctions in C return only single values. If you want to return multiple values, you can pack them into a structure or you can pass pointers as arguments. To return an array declared in a function, such as a <em>char<\/em> array or string, you must assign its value as <em>static<\/em>. Otherwise, like all variables used in a function, its value is discarded when the function ends.<\/p>\n<p>Internally (and forgive my inner nerd for a paragraph), functions return single values by pushing them onto the stack. Only one value is pushed, which can be an <em>int<\/em>, <em>float<\/em>, <em>char<\/em>, <em>struct<\/em>, or an address (pointer). None of these items need be declared <em>static<\/em> within the function as the value is pushed onto the stack. The storage allocated for the variable is lost when the function exits.<\/p>\n<p>The following code shows <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3032\">my <em>binString()<\/em> function<\/a>, which accepts an 8-bit value and returns it as an 8-character string represent a binary number. The <code>bin[]<\/code> array is declared <em>static<\/em> at Line 6.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_07_23-Lesson-a.c\" rel=\"noopener\" target=\"_blank\">2022_07_23-Lesson-a.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n\r\nchar *binString(unsigned char n)\r\n{\r\n    const int width = 8;        <span class=\"comments\">\/* dealing the 8-bit bytes *\/<\/span>\r\n    static char bin[width+1];    <span class=\"comments\">\/* +1 for the null char *\/<\/span>\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* test each bit and set a character for its value *\/<\/span>\r\n    for(x=0;x&lt;width;x++)\r\n    {\r\n        bin[x] = n &amp; 0x80 ? '1' : '0';\r\n        n &lt;&lt;= 1;\r\n    }\r\n    bin[width] = '\\0';        <span class=\"comments\">\/* cap the string *\/<\/span>\r\n\r\n    return(bin);\r\n}\r\n\r\nint main()\r\n{\r\n    int value;\r\n\r\n    printf(\"Enter an integer value, 0 to 255: \");\r\n    scanf(\"%d\",&amp;value);\r\n    printf(\"Binary value is %s\\n\",binString((unsigned char)value));\r\n\r\n    return(0);\r\n}<\/pre>\n<p>Here&#8217;s a sample run:<\/p>\n<p><code>Enter an integer value, 0 to 255: 237<br \/>\nBinary value is 11101101<\/code><\/p>\n<p>If I remove the <em>static<\/em> classifier from Line 6 and recompile, I see a warning: <code>warning: address of stack memory associated with local variable 'bin' returned<\/code> This message means that the return value (on the stack) references a location that no longer exists. Here&#8217;s the output:<\/p>\n<p><code>Enter an integer value, 0 to 255: 237<br \/>\nBinary value is <\/code><\/p>\n<p>The <em>char<\/em> array must be declared <em>static<\/em> or its contents are lost.<\/p>\n<p>Pointers can be pushed to the stack, so returning a pointer&#8217;s value (address) doesn&#8217;t require that the pointer be <em>static<\/em>. The pointer&#8217;s memory must be allocated, of course, as copying an array&#8217;s base to a pointer just returns the address of unallocated memory, which is bad.<\/p>\n<p>No, to retain a string created in a function, its memory must be allocated within the function, as this improvement to the code demonstrates:<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2022_07_23-Lesson-b.c\" rel=\"noopener\" target=\"_blank\">2022_07_23-Lesson-b.c<\/a><\/h3>\n<pre class=\"screen\">\r\n#include &lt;stdio.h&gt;\r\n#include &lt;stdlib.h&gt;\r\n\r\nchar *binString(unsigned char n)\r\n{\r\n    const int width = 8;        <span class=\"comments\">\/* 8-bit bytes *\/<\/span>\r\n    char *bin;        <span class=\"comments\">\/* string storage *\/<\/span>\r\n    int x;\r\n\r\n    <span class=\"comments\">\/* allocate storage *\/<\/span>\r\n    bin = malloc( width * sizeof(char) +1 );\r\n    if( bin==NULL )\r\n        exit(1);\r\n\r\n    <span class=\"comments\">\/* fill storage *\/<\/span>\r\n    for(x=0;x&lt;width;x++)\r\n    {\r\n        bin[x] = n &amp; 0x80 ? '1' : '0';\r\n        n &lt;&lt;= 1;\r\n    }\r\n    bin[width] = '\\0';\r\n\r\n    return(bin);\r\n}\r\n\r\nint main()\r\n{\r\n    int value;\r\n\r\n    printf(\"Enter an integer value, 0 to 255: \");\r\n    scanf(\"%d\",&amp;value);\r\n    printf(\"Binary value is %s\\n\",binString((unsigned char)value));\r\n\r\n    return(0);\r\n}<\/pre>\n<p>The <em>char<\/em> pointer <code>bin<\/code> (Line 7) need not be <em>static<\/em>. Its memory is allocated at Line 11. The address is saved, which is returned from the function intact.<\/p>\n<p>Unlike other functions where memory is allocated, you do not want to free this memory in the function! Wait until after you&#8217;re done using the string. If this program didn&#8217;t quit immediately after output, I would set a <em>free()<\/em> statement in the code to release the allocated memory. Otherwise, the string can be used outside the <em>binString()<\/em> function as you wish, no need to declare it <em>static<\/em>.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>To return a string from a function as a <em>char<\/em> array, it must be static &mdash; not so for a pointer. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=5452\">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-5452","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\/5452","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=5452"}],"version-history":[{"count":4,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5452\/revisions"}],"predecessor-version":[{"id":5462,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/5452\/revisions\/5462"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=5452"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=5452"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=5452"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}