Search code examples
arrayscpointersdma

Problem with passing data from one structore to another using pointers


I have a problem with addressing of data

I'm trying to pass all the data from one structure to another in one go using pointers

When I do this way:

#define ADDRESS_SPACE 8

struct dma_engine
{
    int (*Address)[ADDRESS_SPACE] = {nullptr};
};

struct data_engine
{
    int data[ADDRESS_SPACE] = {0x10,0x14,0x18,0x1B,0x20,0x24,0x28,0x2B};
};

int main(int argc, char* argv[]) 
{
    dma_engine  Dma_0;
    data_engine Data_0;

    Dma_0.Address = &Data_0.data; 
    
    for(int i = 0;i <ADDRESS_SPACE;i++)
    {
        printf("*Dma_0.Address[%d] ---> 0x%x\n",i,*Dma_0.Address[i]);
    }
    printf("\n");

    return 0;
}

I receive only first correct element of the data[ADDRESS_SPACE] array:

*Dma_0.Address[0] ---> 0x10
*Dma_0.Address[1] ---> 0x96408360
*Dma_0.Address[2] ---> 0x77a39b80
*Dma_0.Address[3] ---> 0xb6072bc0
*Dma_0.Address[4] ---> 0x0
*Dma_0.Address[5] ---> 0x0
*Dma_0.Address[6] ---> 0x96408368
*Dma_0.Address[7] ---> 0x0

Is there a way to pass all the correct data in one go rather than handle every element of an array individually?

Many Thanks


Solution

  • Assuming you truly desire a strongly-typed pointer-to-array as your Address member, the code you have is not dereferencing the target array correctly during your print loop. Specifically, this:

    *Dma_0.Address[i]
    

    That member is a pointer to array-of-8-int. The syntax applies both * and [i] in the same expression against the same operand, which is not what you want. [] has higher precedence than * in C when applied in this context.

    Therefore you may think that expression means:

    • dereference the pointer-to-array using * to get the base array
    • apply [i] against that array to acquire the desired i'th element.

    But in actuality what you're asking is:

    • find the i'th array-of-8-int, starting at the specified address.
    • use * to acquire the first element of that array

    Solution

    Assuming you want to retain all of your existing type usage, the solution is to simply force the evaluation of * first by encasing it in something with higher priority than [] . Expression parenthesis has the highest priority in the language, and will deliver what you desire.

    Therefore,

    (*Dma_0.Address)[i]
    

    which says: evaluate *Dma_0.Address before applying [i] to the result. This one change in your program produces the following output*:

    *Dma_0.Address[0] ---> 0x10
    *Dma_0.Address[1] ---> 0x14
    *Dma_0.Address[2] ---> 0x18
    *Dma_0.Address[3] ---> 0x1b
    *Dma_0.Address[4] ---> 0x20
    *Dma_0.Address[5] ---> 0x24
    *Dma_0.Address[6] ---> 0x28
    *Dma_0.Address[7] ---> 0x2b
    

    which I suspect is what you're really after.

    * I did not bother changing any of the printf messaging, opting only to change the problematic argument, when I tested this, in case that wasn't obvious