1

I have problems when allocating memory on a Tiva C launchpad (ARM Cortex M4), what I am trying to do is to dynamically allocate a pointer to pointers to structure inside another structure, at some point calloc() returns a pointer which is the same value as the address where the pointer is stored.

I find this a bit difficult to explain, so I made this code which illustrates what I want to do and that works perfectly fine on here, but it doesn't work the same way in my application.

#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <stddef.h>

typedef struct
{
    uint32_t    Pin;
    uint32_t    Port;
} fGpio_Pin;

typedef struct
{
    uint32_t    Mode;
    uint32_t    nPins;
    fGpio_Pin** Pins;
} fSpi_Mod;

fSpi_Mod* Spi;

void printSizes (void)
{
    printf("Size of uint8_t: %i bytes.\n", sizeof(uint8_t));
    printf("Size of uint16_t: %i bytes.\n", sizeof(uint16_t));
    printf("Size of uint32_t: %i bytes.\n", sizeof(uint32_t));
    printf("Size of uint64_t: %i bytes.\n", sizeof(uint64_t));
    printf("Size of fSpi_Mod*: %i bytes.\n", sizeof(fSpi_Mod*));
    printf("Size of fSpi_Mod: %i bytes.\n", sizeof(fSpi_Mod));
    printf("Size of fGpio_Pin**: %i bytes.\n", sizeof(fGpio_Pin**));
    printf("Size of fGpio_Pin*: %i bytes.\n", sizeof(fGpio_Pin*));
    printf("Size of fGpio_Pin: %i bytes.\n", sizeof(fGpio_Pin));
    printf("----\n");
}

void printStructure (fSpi_Mod* Spi_Mod)
{
    uint8_t i;

    printf("The address of the structure is 0x%X.\n", Spi_Mod);
    printf("The value of mode is 0x%X and address 0x%X.\n", Spi_Mod->Mode, &(Spi_Mod->Mode));
    printf("The value of nPins is 0x%X and address 0x%X.\n", Spi_Mod->nPins, &(Spi_Mod->nPins));
    printf("The value of Pins is 0x%X and address 0x%X.\n", Spi_Mod->Pins, &(Spi_Mod->Pins));

    for (i = 0; i < Spi_Mod->nPins; i++)
    {
        printf("#%i | The pointer that points to Gpio structure is 0x%X at address 0x%X.\n", i, *(Spi_Mod->Pins + i), &(*(Spi_Mod->Pins + i)));
        printf("#%i | The value of Pin of Gpio structure is 0x%X and address 0x%X.\n", i, ((*(Spi_Mod->Pins + i)))->Pin, &(((*(Spi_Mod->Pins + i)))->Pin));
        printf("#%i | The value of Port of Gpio structure is 0x%X and address 0x%X.\n", i, ((*(Spi_Mod->Pins + i)))->Port, &(((*(Spi_Mod->Pins + i)))->Port));
    }
    printf("----\n");
}

int main()
{
    uint8_t i = 0;

    printf(">>>> Begin program.\n");

    printSizes();

    Spi = (fSpi_Mod*) calloc(1, sizeof(fSpi_Mod));
    if (Spi == NULL) {
        printf("Insufficient memory.\n");
        return 1;
    }

    //printStructure(Spi);
    Spi->Mode = 0x05;
    Spi->nPins = 0x04;

    Spi->Pins = (fGpio_Pin**) calloc(Spi->nPins, sizeof(fGpio_Pin*));
    if (Spi->Pins == NULL) 
    {
        printf("Insufficient memory.\n");
        return 1;
    }

    //printStructure(Spi);

    for (i = 0; i < Spi->nPins; i++)
    {
        (*(Spi->Pins + i)) = (fGpio_Pin*) calloc(1, sizeof(fGpio_Pin));
        if ((*(Spi->Pins + i)) == NULL) 
        {
            printf("Insufficient memory.\n");
            return 1;
        }
    }

    printStructure(Spi);

    printf(">>>> End program.\n");
}

In my application, when I try to allocate four pointers of type "pointer to (fGpio_Pin*)" and cast it to (fGpio_Pin**), calloc() returns the address of Spi->Pins, so basically the address of Spi->Pins and its value are the same and it becomes a pointer to itself, and that is when problems begin to appear.

There is enough memory in the heap and calloc() doesn't return a NULL pointer, could this be implementation dependant? I am using TI ARM Compiler and Code Composer Studio, not gcc.

Perhaps I am missing something so I will keep looking. Thank you for your time.

Edit1:

This is the output of the code above, which works OK.

>>>> Begin program.                                                                                                                                                                                                                            
Size of uint8_t: 1 bytes.                                                                                                                                                                                                                      
Size of uint16_t: 2 bytes.                                                                                                                                                                                                                     
Size of uint32_t: 4 bytes.                                                                                                                                                                                                                     
Size of uint64_t: 8 bytes.                                                                                                                                                                                                                     
Size of fSpi_Mod*: 8 bytes.                                                                                                                                                                                                                    
Size of fSpi_Mod: 24 bytes.                                                                                                                                                                                                                    
Size of fGpio_Pin**: 8 bytes.                                                                                                                                                                                                                  
Size of fGpio_Pin*: 8 bytes.                                                                                                                                                                                                                   
Size of fGpio_Pin: 8 bytes.                                                                                                                                                                                                                    
----                                                                                                                                                                                                                                           
The address of the structure is 0x1DF7010.                                                                                                                                                                                                     
The value of mode is 0x5 and address 0x1DF7010.                                                                                                                                                                                                
The value of nPins is 0x4 and address 0x1DF7014.                                                                                                                                                                                               
The value of Pins is 0x1DF7030 and address 0x1DF7018.                                                                                                                                                                                          
#0 | The pointer that points to Gpio structure is 0x1DF7060 at address 0x1DF7030.                                                                                                                                                              
#0 | The value of Pin of Gpio structure is 0x0 and address 0x1DF7060.                                                                                                                                                                          
#0 | The value of Port of Gpio structure is 0x0 and address 0x1DF7064.                                                                                                                                                                         
#1 | The pointer that points to Gpio structure is 0x1DF7080 at address 0x1DF7038.                                                                                                                                                              
#1 | The value of Pin of Gpio structure is 0x0 and address 0x1DF7080.                                                                                                                                                                          
#1 | The value of Port of Gpio structure is 0x0 and address 0x1DF7084.                                                                                                                                                                         
#2 | The pointer that points to Gpio structure is 0x1DF70A0 at address 0x1DF7040.                                                                                                                                                              
#2 | The value of Pin of Gpio structure is 0x0 and address 0x1DF70A0.                                                                                                                                                                          
#2 | The value of Port of Gpio structure is 0x0 and address 0x1DF70A4.                                                                                                                                                                         
#3 | The pointer that points to Gpio structure is 0x1DF70C0 at address 0x1DF7048.                                                                                                                                                              
#3 | The value of Pin of Gpio structure is 0x0 and address 0x1DF70C0.                                                                                                                                                                          
#3 | The value of Port of Gpio structure is 0x0 and address 0x1DF70C4.                                                                                                                                                                         
----                                                                                                                                                                                                                                           
>>>> End program.  

In my application (I can't post images I don't have enough reputation):

After the calloc: After the calloc:

trincot
  • 317,000
  • 35
  • 244
  • 286
Mite
  • 57
  • 1
  • 9
  • 3
    `*(Spi->Pins + i)` -> `Spi->Pins[i]` would cause way less confusion. And, [Do not cast the result of `malloc()`](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). Also, if `calloc()` didn't return `NULL`, there is no problem, it's guaranteed AFAIK to return a valid address, what is the actual problem? – Iharob Al Asimi Feb 21 '15 at 14:45
  • 2
    can you show the output you get when you run that program? – wimh Feb 21 '15 at 14:49
  • 2
    Yes please the output, because you apparently used the `&` address of operator wrong when printing the values pointer and you printed addresses of the pointers. – Iharob Al Asimi Feb 21 '15 at 14:50
  • The code involving `calloc()` looks good, besides the fact there is no need to cast in C, nor that it is recommended to do so. – alk Feb 21 '15 at 15:02
  • I added more information, thanks for the help. – Mite Feb 21 '15 at 15:02
  • Your output included `The value of Pins is 0x1DF7030 and address 0x1DF7018`, so it is not a pointer to itself? – wimh Feb 21 '15 at 15:11
  • You are correct Wimmel, the output of the code I presented illustrates what I want to do, and it works fine. But in my application it doesn't, check the image I've attached. Both codes are the same but compiled by different compilers (GNU GCC and TI ARM COMPILER), so I don't know if this is application specific or I am missing something. – Mite Feb 21 '15 at 15:13
  • But this is the output of your application. So your application works fine. Maybe the debugger is wrong or confuses you? – wimh Feb 21 '15 at 15:15
  • The value of `&(Spi_Mod->Mode)` had better be the same address as that reported as the value of `Spi_Mod`, or your compiler wouldn't be placing the first element of the structure at the base address of the structure itself, which it is required to per the standard. I still don't see the problem. (though I would be using `%p` for printing all those addresses if available on your platform). – WhozCraig Feb 21 '15 at 15:16
  • "*or your compiler wouldn't be placing the first element of the structure at the base address of the structure itself.*" This would indicate a bug in the compiler. @WhozCraig – alk Feb 21 '15 at 15:18
  • @alk exactly correct. – WhozCraig Feb 21 '15 at 15:18
  • It's not the output of my application, my application doesn't work as I expect, when I try to allocate the fGpio structures the calloc sets everything ot zero, and the same code detects a null pointer and exits. The code is the same but compiled by different compilers and executed by different machines, I could set an UART on my board and print the output but currently I am using the debugger for this purpose. Thank you for your time. – Mite Feb 21 '15 at 15:21
  • I will recheck everything again I spent quite a few hours on this and probably I am missing something – Mite Feb 21 '15 at 15:23
  • What doesn't make sense to me is why in my application the calloc allocates four pointers of type pointer to fGpio_Pin at the same location where the pointer to these four pointers has been previously allocated when I called calloc with the Spi structure. I mean, the pointer to those four pointers and other members of the Spi structure are stored in the same space. In my application this is what happens, in the code I provided run under GNU GCC and a different machine it does not. – Mite Feb 21 '15 at 15:37
  • `sizeof` yields a result of type `size_t`. The correct format for printing a `size_t` value is `%zu`, not `%i` (and yes, it can make a difference). Also, the solution should be posted as an answer, or perhaps as a comment if it's merely a clarification, not included in the body of the question. – Keith Thompson Feb 21 '15 at 20:22
  • Thanks for the tip, and apologies, now the solution is posted as an answer. – Mite Feb 21 '15 at 20:47
  • Are you saying that printf( "address: %p, contents: %p\n", &Spi, *Spi ); results in both values being the same? – user3629249 Feb 21 '15 at 22:15
  • 1) the returned value from calloc (and family) should always be checked to assure the operation was successful 2) in C, the returned value from calloc (and family) should not be cast. – user3629249 Feb 21 '15 at 22:17

2 Answers2

0

I think your first calloc call is allocating insufficient memory. From the screenshot of the debugger you posted:

SpiRfid = (fSpi_Mod*) calloc(1, sizeof(SpiRfid));

This will allocate only enough memory for the pointer, not the structure. You probably want

SpiRfid = (fSpi_Mod*) calloc(1, sizeof(*SpiRfid));
  • You are correct and many thanks, it solved the issue for me. This was a huge typo on my part which has caused me many headaches, I can't believe I didn't notice it earlier. the sizeof operator in this line was written incorrectly, I fixed it and everything now works as expected. – Mite Feb 21 '15 at 16:08
0

As seen on the image and pointed out by Matthew Wightman, the first calloc is incorrect, specifically the sizeof operator. The sizeof operator in the image allocated space for a pointer of type pointer to fSpi_Mod structure (SpiRfid is a variable of this kind) and I what I intended was to allocate space for a fSpi_Mod structure. This was a typo on my part.

Therefore, changing this:

sizeof(SpiRfid)

To this:

sizeof(fSpi_Mod)

Made it work. This is just one possible solution.

Mite
  • 57
  • 1
  • 9