{"id":3373,"date":"2018-11-24T00:01:57","date_gmt":"2018-11-24T08:01:57","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=3373"},"modified":"2018-11-17T14:36:42","modified_gmt":"2018-11-17T22:36:42","slug":"dealing-with-structures-pointers-and-files","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=3373","title":{"rendered":"Dealing with Structures, Pointers, and Files"},"content":{"rendered":"<p>For pointer structures, the process of writing the structure to a file works similarly to writing a non-pointer structure, but it&#8217;s not without some pratfalls. Further, if you have a structure that contains a pointer, things get hinkey quickly.<br \/>\n<!--more--><br \/>\nWhen the code declares an array of structure pointers, the process of writing those structures to a file involves ensuring that you&#8217;re writing the data and not the pointer itself. For example:<\/p>\n<p><code>struct person {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;char name[32];<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int age;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;float weight;<br \/>\n};<br \/>\nstruct person *myself;<\/code><\/p>\n<p>The <code>struct person<\/code> variable <code>myself<\/code> is a pointer. Storage must be allocated for the pointer to reference:<\/p>\n<p><code>myself = (struct person *)malloc( sizeof(struct person) * 1);<br \/>\nif( myself == NULL)<br \/>\n{<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;fprintf(stderr,\"Unable to allocate memory\\n\");<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;exit(1);<br \/>\n}<\/code><\/p>\n<p>The <em>malloc()<\/em> function sets aside a chunk of memory equal to the <em>sizeof<\/em> the <code>person<\/code> structure. After success, the structure is filled with data:<\/p>\n<p><code>strcpy( myself-&gt;name,\"Dan Gookin\");<br \/>\nmyself-&gt;age = 58;<br \/>\nmyself-&gt;weight = 679.1;<\/code><\/p>\n<p>At this point, you can write the structure to a file. Use the <em>fwrite()<\/em> function as shown in <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3346\">this Lesson<\/a>, but pay attention! What are you writing to the file?<\/p>\n<p>Here is the proper <em>fwrite()<\/em> statement, assuming <code>fp<\/code> is an open file handle:<\/p>\n<p><code>fwrite(myself,sizeof(struct person),1,fp);<\/code><\/p>\n<p>And here is the improper <em>fwrite()<\/em> statement:<\/p>\n<p><code>fwrite(&amp;myself,sizeof(struct person),1,fp);<\/code><\/p>\n<p>The address-of operator (<code>&amp;<\/code>) isn&#8217;t required when writing a structure pointer because <code>myself<\/code> is already a pointer. If you apply the ampersand, you write the address of the <code>myself<\/code> structure and not the structure&#8217;s data.<\/p>\n<p>The other pointer issue occurs when the structure contains a pointer member. I&#8217;ll be brief: Don&#8217;t even bother. The overhead required to write the pointer member&#8217;s data is too great and often too inconsistent to be worth the trouble. In fact, if you must write structures to a file, never include pointer members in the structure.<\/p>\n<p>As an example, suppose the <code>person<\/code> structure were defined like this:<\/p>\n<p><code>struct person {<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;char *name;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;int age;<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;float weight;<br \/>\n};<br \/>\nstruct person *myself;<\/code><\/p>\n<p>As the code runs, you&#8217;d allocate storage for the <code>name<\/code> pointer, fill the buffer, and so on. When it comes time to write the structure to a file, the <em>sizeof<\/em> operator returns only the bytes required to save the <code>name<\/code> pointer, not the buffer.<\/p>\n<p>Suppose I allocate storage for <code>name<\/code> when the input is <code>\"Dan Gookin<\/code>&#8221; (11 bytes). The <code>name<\/code> pointer member occupies only 4 bytes on my system. I just can&#8217;t think of a logical or consistent way to reference the buffer&#8217;s data without destroying the concept of writing specific-size chunks to a file. It&#8217;s too much of a bother, which is why I recommend not writing structures to a file when the structure includes pointer members.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>My advice is to avoid using pointers when your desire is to read and write structures to a file. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=3373\">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-3373","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\/3373","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=3373"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3373\/revisions"}],"predecessor-version":[{"id":3381,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/3373\/revisions\/3381"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=3373"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=3373"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=3373"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}