Calloc возвращает указатель на себя

У меня проблемы при распределении памяти на панели запуска Tiva C (ARM Cortex M4), я пытаюсь динамически выделить указатель на указатели для структуры внутри другой структуры, в какой-то момент calloc() возвращает указатель, значение которого совпадает с адресом, где хранится указатель.

Мне немного сложно это объяснить, поэтому я создал этот код, который иллюстрирует то, что я хочу сделать, и здесь он прекрасно работает, но в моем приложении он работает не так.

#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");
}

В моем приложении, когда я пытаюсь выделить четыре указателя типа "указатель на (fGpio_Pin*)и брось (fGpio_Pin**), calloc() возвращает адрес Spi->Pinsтак что в основном адрес Spi->Pins и его значения одинаковы, и он становится указателем на себя, и именно тогда начинают появляться проблемы.

Достаточно памяти в куче и calloc() не возвращает NULL указатель, это может быть зависит от реализации? Я использую TI ARM Compiler и Code Composer Studio, а не gcc.

Возможно, я что-то упустил, поэтому я буду продолжать искать. Спасибо за ваше время.

Edit1:

Это вывод кода выше, который работает нормально.

>>>> 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.  

В моем приложении (я не могу публиковать изображения, у меня недостаточно репутации):

После кальлока:После кальлока

2 ответа

Решение

Я думаю, что ваш первый вызов calloc выделяет недостаточно памяти. На скриншоте отладчика, который вы разместили:

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

Это выделит только достаточно памяти для указателя, а не для структуры. Вы, вероятно, хотите

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

Как видно на изображении и на что указывает Мэтью Вайтман, первый calloc неправильный, в частности оператор sizeof. Оператор sizeof в изображении выделил пространство для указателя типа указатель на структуру fSpi_Mod (SpiRfid - переменная такого типа), и я намеревался выделить место для структуры fSpi_Mod. Это была опечатка с моей стороны.

Поэтому меняем это:

sizeof(SpiRfid)

К этому:

sizeof(fSpi_Mod)

Сделано это работает. Это только одно из возможных решений.

Другие вопросы по тегам