Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>I suggest that you build this out a layer at a time using typdefs to create layers of types. By doing so, the different types needed will be much clearer.</p> <p>For instance:</p> <pre><code>typedef struct Test { int data; } TestType; typedef TestType * PTestType; </code></pre> <p>This will create two new types, one for the struct and one for a pointer to the struct.</p> <p>So next if you want an array of the structs then you would use:</p> <pre><code>TestType array[20]; // creates an array of 20 of the structs </code></pre> <p>If you want an array of pointers to the structs then you would use:</p> <pre><code>PTestType array2[20]; // creates an array of 20 of pointers to the struct </code></pre> <p>Then if you want to allocate structs into the array you would do something like:</p> <pre><code>PTestType array2[20]; // creates an array of 20 of pointers to the struct // allocate memory for the structs and put their addresses into the array of pointers. for (int i = 0; i &lt; 20; i++) { array2 [i] = malloc (sizeof(TestType)); } </code></pre> <p>C does not allow you to assign one array to another. You must instead use a loop to assign each element of one array to an element of the other.</p> <p><strong>EDIT: Another Interesting Approach</strong></p> <p>Another approach would be a more object oriented approach in which you encapsulate a few things. For instance using the same layers of types we create two types:</p> <pre><code>typedef struct _TestData { struct { int myData; // one or more data elements for each element of the pBlob array } *pBlob; int nStructs; // count of number of elements in the pBlob array } TestData; typedef TestData *PTestData; </code></pre> <p>Next we have a helper function which we use to create the object, named appropriately enough <code>CreateTestData (int nArrayCount)</code>.</p> <pre><code>PTestData CreateTestData (int nCount) { PTestData ret; // allocate the memory for the object. we allocate in a single piece of memory // the management area as well as the array itself. We get the sizeof () the // struct that is referenced through the pBlob member of TestData and multiply // the size of the struct by the number of array elements we want to have. ret = malloc (sizeof(TestData) + sizeof(*(ret-&gt;pBlob)) * nCount); if (ret) { // make sure the malloc () worked. // the actual array will begin after the end of the TestData struct ret-&gt;pBlob = (void *)(ret + 1); // set the beginning of the array ret-&gt;nStructs = nCount; // set the number of array elements } return ret; } </code></pre> <p>Now we can use our new object as in the source code segment below. It should check that the pointer returned from CreateTestData() is valid however this is really just to show what could be done.</p> <pre><code>PTestData go = CreateTestData (20); { int i = 0; for (i = 0; i &lt; go-&gt;nStructs; i++) { go-&gt;pBlob[i].myData = i; } } </code></pre> <p>In a truly dynamic environment you may also want to have a <code>ReallocTestData(PTestData p)</code> function that would reallocate a <code>TestData</code> object in order to modify the size of the array contained in the object.</p> <p>With this approach, when you are done with a particular TestData object, you can just free the object as in <code>free (go)</code> and the object and its array are both freed at the same time.</p> <p><strong>Edit: Extending Further</strong></p> <p>With this encapsulated type we can now do a few other interesting things. For instance, we can have a copy function, <code>PTestType CreateCopyTestData (PTestType pSrc)</code> which would create a new instance and then copy the argument to a new object. In the following example, we reuse the function <code>PTestType CreateTestData (int nCount)</code> that will create an instance of our type, using the size of the object we are copying. After doing the create of the new object, we make a copy of the data from the source object. The final step is to fix up the pointer which in the source object points to its data area so that pointer in the new object now points to the data area of itself rather than the data area of the old object.</p> <pre><code>PTestType CreateCopyTestData (PTestType pSrc) { PTestType pReturn = 0; if (pSrc) { pReturn = CreateTestData (pSrc-&gt;nStructs); if (pReturn) { memcpy (pReturn, pSrc, sizeof(pTestType) + pSrc-&gt;nStructs * sizeof(*(pSrc-&gt;pBlob))); pReturn-&gt;pBlob = (void *)(pReturn + 1); // set the beginning of the array } } return pReturn; } </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload