1

I am debugging some code and just wanted to make sure that the way I am setting a pointer to an array inside my struct is correct.

Here is an example of what I am trying to do:

typedef struct Foo
{
    uint32_t *bar;
} Foo

int main(void)
{
    Foo *foo;
    uint32_t *bar[20];

    foo = (Foo *)malloc(sizeof(Foo));
    *bar = malloc(sizeof(uint32_t) * 20);

    for(int i = 0; i < 20; i++)
    {
        bar[i] = (uint32_t*)malloc(sizeof(uint32_t));
    } 

    foo->bar = *bar;
}
Alex
  • 41
  • 4
  • 1
    Don't cast `malloc` in C: http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc – asimes May 04 '15 at 00:05

2 Answers2

2

The code

uint32_t *bar[20];

declares bar as an array of 20 pointers to uint32_t which is probably not what you intended. Since you allocate the array dynamically with malloc, you should declare bar as a pointer rather than an array:

uint32_t **bar;
vitaut
  • 49,672
  • 25
  • 199
  • 336
0

You may want to consider doing the memory allocation in a single malloc() rather than the piecewise approach you are using. For instance you might want to consider doing something like the following.

This allocates the memory needed in a single call to malloc() so that only a single call to free() is needed to release the memory. It is faster and tends to make the heap to be less fragmented and easier to manage.

typedef struct
{
    uint32_t *bar[1];  // an array of size one that makes array syntax easy
} Foo;

Foo *FooCreateFoo (unsigned int nCount)
{
    // create an array of pointers to uint32_t values along with the
    // memory area for those uint32_t data values.
    Foo *p = malloc (sizeof(uint32_t *) * nCount + sizeof(uint32_t) * nCount);

    if (p) {
        // we have memory allocated so now initialize the array of pointers
        unsigned int iLoop;
        uint32_t *pData = p->bar + nCount;  // point to past the last array element
        for (iLoop = 0; iLoop < nCount; iLoop++) {
            // set the pointer value and initialize the data to zero.
            *(p->bar[iLoop] = pData++) = 0;
        }
    }

    return p;
}

int main(void)
{
    Foo *foo = FooCreateFoo (20);

    if (! foo) {
        //  memory allocation failed so exit out.
        return 1;
    }

    // ...  do things with foo by dereferencing the pointers in the array as in
    *(foo->bar[1]) += 3;  // increment the uint32_t pointed to by a value of 3

    free (foo);       // we be done with foo so release the memory
}
Richard Chambers
  • 16,643
  • 4
  • 81
  • 106