{"id":7209,"date":"2025-10-25T00:01:21","date_gmt":"2025-10-25T07:01:21","guid":{"rendered":"https:\/\/c-for-dummies.com\/blog\/?p=7209"},"modified":"2025-10-18T11:13:22","modified_gmt":"2025-10-18T18:13:22","slug":"filling-the-pointer-pointers-with-data","status":"publish","type":"post","link":"https:\/\/c-for-dummies.com\/blog\/?p=7209","title":{"rendered":"Filling the Pointer Pointers with Data"},"content":{"rendered":"<p>The final step of the pointer storage program is to add data to the various buffers, or &#8220;sticks,&#8221; where ten integer values are stored. This step involves ugly double-pointer notation. If you can, please review <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7201\">last week&#8217;s Lesson<\/a> to get up to speed on how storage is allocated and how these pointers are managed.<br \/>\n<!--more--><br \/>\nWhen I first coded this program, I wrote it in the manner presented over the past few weeks, one step at a time. I feel that the best way to write something weird like managing pointers is to do so incrementally. The final step is to add values to each of the allocated sticks and then output the values once everything is allocated.<\/p>\n<p>The following code adds two items to the code shown in last week&#8217;s Lesson: statements to assign the values and statements to output the results. Both use a similar oddball expression to access the individual values, which is the point of this Lesson.<\/p>\n<h3><a href=\"https:\/\/github.com\/dangookin\/C-For-Dummies-Blog\/blob\/master\/2025_10_25-Lesson.c\" rel=\"noopener\" target=\"_blank\">2025_10_25-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;time.h&gt;\r\n\r\n<span class=\"comments\">\/* allocate storage for ten integers *\/<\/span>\r\nint *ten(void)\r\n{\r\n    int *iptr = NULL;\r\n\r\n    iptr = malloc( sizeof(int) * 10 );\r\n\r\n    return(iptr);\r\n}\r\n\r\nint main()\r\n{\r\n    int **tenint = NULL;\r\n    int x,y;\r\n\r\n    <span class=\"comments\">\/* seed the randomizer *\/<\/span>\r\n    srand( (unsigned)time(NULL) );\r\n\r\n    <span class=\"comments\">\/* allocate 10 sticks of 10 integers *\/<\/span>\r\n    for( y=0; y&lt;10; y++ )\r\n    {\r\n        <span class=\"comments\">\/* allocate first stick *\/<\/span>\r\n        if( tenint==NULL )\r\n        {\r\n            tenint = malloc( sizeof( int *) );\r\n            if( tenint==NULL )\r\n            {\r\n                fprintf(stderr,\"Unable to allocate storage\\n\");\r\n                exit(1);\r\n            }\r\n        }\r\n        else\r\n        <span class=\"comments\">\/* allocate additional sticks *\/<\/span>\r\n        {\r\n            tenint = realloc(tenint, sizeof( int *) * (y+1) );\r\n            if( tenint==NULL )\r\n            {\r\n                fprintf(stderr,\"Unable to reallocate storage\\n\");\r\n                exit(1);\r\n            }\r\n        }\r\n        <span class=\"comments\">\/* get the storage *\/<\/span>\r\n        *(tenint+y) = ten();\r\n        if( *(tenint+y)==NULL )\r\n        {\r\n            fprintf(stderr,\"Unable to allocate stick %d\\n\",y);\r\n            exit(1);\r\n        }\r\n        printf(\"Stick %d allocated\\n\",y);\r\n\r\n        <span class=\"comments\">\/* assign the values *\/<\/span>\r\n        for( x=0; x&lt;10; x++ )\r\n            *(*(tenint+y)+x) = rand() % 10 + 10*(y+1);\r\n    }\r\n\r\n    <span class=\"comments\">\/* output the results *\/<\/span>\r\n    for( y=0; y&lt;10; y++ )\r\n    {\r\n        printf(\"Stick %d: \",y);\r\n        for( x=0; x&lt;10; x++ )\r\n            printf(\"%3d \",*(*(tenint+y)+x) );\r\n        putchar('\\n');\r\n    }\r\n\r\n    <span class=\"comments\">\/* clean-up *\/<\/span>\r\n    for( y=0; y&lt;10; y++ )\r\n        free( *(tenint+y) );\r\n    free(tenint);\r\n    puts(\"All sticks freed\");\r\n    return 0;\r\n}<\/pre>\n<p>The first new bit of code appears inside the nested loop, under the comment <code>\/* assign the values *\/<\/code>:<\/p>\n<p><code>for( x=0; x&lt;10; x++ )<br \/>\n&nbsp;&nbsp;&nbsp;&nbsp;*(*(tenint+y)+x) = rand() % 10 + 10*(y+1);<\/code><\/p>\n<p>The right side of the expression generates a random value based on the value of variable <code>y<\/code>. The left side of the equation features this contraption:<\/p>\n<p><code>*(*(tenint+y)+x)<\/code><\/p>\n<p>As with anything ugly in programming, it helps to work from the inside out.<\/p>\n<p><code>tenint<\/code> is the address were a series of pointers are stored.<\/p>\n<p><code>tenint+y<\/code> is an offset into the buffer where the pointers are stored. It represents addresses (pointers) zero through <code>y<\/code>, as stored in the <code>tenint<\/code> buffer.<\/p>\n<p><code>*(tenint+y)<\/code> is the address stored at offset <code>y<\/code>. So if <code>y==3<\/code>, <code>*(tenint+y)<\/code> represents the fourth value (address) stored in the buffer, the location of a ten-integer stick in memory. An equivalent in array notation would be <code>tenint[y]<\/code>. (But remember that array notation isn&#8217;t a substitute for using pointers.)<\/p>\n<p><code>*(tenint+y)+x<\/code> is an offset from the address <code>*(tenint+y)<\/code>. The result is still an address, but at an offset within the stick where the ten integers are stored. For example, if <code>x==7<\/code>, <code>*(tenint+y)+x<\/code> is the address of the eighth integer in the stick. The array notation equivalent would be <code>tenint[y][x]<\/code>. This value is still an address.<\/p>\n<p><code>*(*(tenint+y)+x)<\/code> is a value, the integer, stored at address <code>*(tenint+y)+x<\/code>.<\/p>\n<p>As the value of <code>x<\/code> increases, each subsequent integer in the stick is fetched. Then the outer <code>y<\/code> loop repeats to reference the next stick stored in the <code>tenint<\/code> buffer.<\/p>\n<p>Here&#8217;s the program&#8217;s output:<\/p>\n<p><code>Stick&nbsp;0&nbsp;allocated<br \/>\nStick&nbsp;1&nbsp;allocated<br \/>\nStick&nbsp;2&nbsp;allocated<br \/>\nStick&nbsp;3&nbsp;allocated<br \/>\nStick&nbsp;4&nbsp;allocated<br \/>\nStick&nbsp;5&nbsp;allocated<br \/>\nStick&nbsp;6&nbsp;allocated<br \/>\nStick&nbsp;7&nbsp;allocated<br \/>\nStick&nbsp;8&nbsp;allocated<br \/>\nStick&nbsp;9&nbsp;allocated<br \/>\nStick&nbsp;0:&nbsp;&nbsp;14&nbsp;&nbsp;19&nbsp;&nbsp;10&nbsp;&nbsp;15&nbsp;&nbsp;18&nbsp;&nbsp;14&nbsp;&nbsp;15&nbsp;&nbsp;17&nbsp;&nbsp;16&nbsp;&nbsp;14&nbsp;<br \/>\nStick&nbsp;1:&nbsp;&nbsp;22&nbsp;&nbsp;26&nbsp;&nbsp;21&nbsp;&nbsp;29&nbsp;&nbsp;23&nbsp;&nbsp;22&nbsp;&nbsp;20&nbsp;&nbsp;20&nbsp;&nbsp;29&nbsp;&nbsp;23&nbsp;<br \/>\nStick&nbsp;2:&nbsp;&nbsp;38&nbsp;&nbsp;36&nbsp;&nbsp;33&nbsp;&nbsp;30&nbsp;&nbsp;36&nbsp;&nbsp;32&nbsp;&nbsp;32&nbsp;&nbsp;37&nbsp;&nbsp;37&nbsp;&nbsp;34&nbsp;<br \/>\nStick&nbsp;3:&nbsp;&nbsp;46&nbsp;&nbsp;43&nbsp;&nbsp;45&nbsp;&nbsp;48&nbsp;&nbsp;40&nbsp;&nbsp;43&nbsp;&nbsp;44&nbsp;&nbsp;46&nbsp;&nbsp;40&nbsp;&nbsp;40&nbsp;<br \/>\nStick&nbsp;4:&nbsp;&nbsp;52&nbsp;&nbsp;54&nbsp;&nbsp;58&nbsp;&nbsp;55&nbsp;&nbsp;56&nbsp;&nbsp;52&nbsp;&nbsp;58&nbsp;&nbsp;56&nbsp;&nbsp;54&nbsp;&nbsp;59&nbsp;<br \/>\nStick&nbsp;5:&nbsp;&nbsp;60&nbsp;&nbsp;65&nbsp;&nbsp;67&nbsp;&nbsp;65&nbsp;&nbsp;65&nbsp;&nbsp;64&nbsp;&nbsp;67&nbsp;&nbsp;69&nbsp;&nbsp;63&nbsp;&nbsp;66&nbsp;<br \/>\nStick&nbsp;6:&nbsp;&nbsp;75&nbsp;&nbsp;71&nbsp;&nbsp;71&nbsp;&nbsp;70&nbsp;&nbsp;79&nbsp;&nbsp;71&nbsp;&nbsp;75&nbsp;&nbsp;75&nbsp;&nbsp;77&nbsp;&nbsp;75&nbsp;<br \/>\nStick&nbsp;7:&nbsp;&nbsp;85&nbsp;&nbsp;81&nbsp;&nbsp;82&nbsp;&nbsp;84&nbsp;&nbsp;87&nbsp;&nbsp;88&nbsp;&nbsp;88&nbsp;&nbsp;85&nbsp;&nbsp;84&nbsp;&nbsp;82&nbsp;<br \/>\nStick&nbsp;8:&nbsp;&nbsp;96&nbsp;&nbsp;94&nbsp;&nbsp;99&nbsp;&nbsp;93&nbsp;&nbsp;99&nbsp;&nbsp;95&nbsp;&nbsp;97&nbsp;&nbsp;98&nbsp;&nbsp;96&nbsp;&nbsp;91&nbsp;<br \/>\nStick&nbsp;9:&nbsp;104&nbsp;102&nbsp;102&nbsp;105&nbsp;102&nbsp;104&nbsp;109&nbsp;108&nbsp;109&nbsp;106&nbsp;<br \/>\nAll&nbsp;sticks&nbsp;freed<\/code><\/p>\n<p>The point to all this is to manage a collection of allocated addresses, expanding this collection as new sticks are added. A more common way to deal with such an operation might be to create a linked list. But my point is more to teach the double-pointer concept when it comes to allocating, managing, and accessing storage.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Time to wrap up the code by putting data into the buffers, then accessing the data by using a double-pointer. <a href=\"https:\/\/c-for-dummies.com\/blog\/?p=7209\">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-7209","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\/7209","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=7209"}],"version-history":[{"count":3,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7209\/revisions"}],"predecessor-version":[{"id":7216,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=\/wp\/v2\/posts\/7209\/revisions\/7216"}],"wp:attachment":[{"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=7209"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=7209"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/c-for-dummies.com\/blog\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=7209"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}