【问题标题】:calloc returns a pointer to itselfcalloc 返回一个指向自身的指针
【发布时间】:2015-04-23 04:45:07
【问题描述】:

我在 Tiva C 启动板(ARM Cortex M4)上分配内存时遇到问题,我想做的是动态分配一个指向另一个结构内结构的指针的指针,在某些时候calloc() 返回一个指针与存储指针的地址相同。

我觉得这有点难以解释,所以我编写了这段代码来说明我想要做什么,并且在 here 上运行得非常好,但它在我的应用程序中的运行方式不同。

#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-&gt;Pins 的地址,所以基本上是Spi-&gt;Pins 的地址和它的值是一样的,变成一个指向自己的指针,这时候问题就开始出现了。

堆中有足够的内存并且calloc() 没有返回NULL 指针,这可能与实现有关吗?我使用的是 TI ARM Compiler 和 Code Composer Studio,而不是 gcc。

也许我错过了一些东西,所以我会继续寻找。感谢您的宝贵时间。

编辑1:

这是上面代码的输出,可以正常工作。

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

在我的应用程序中(我无法发布我没有足够声誉的图片):

调用之后:

【问题讨论】:

  • *(Spi-&gt;Pins + i) -> Spi-&gt;Pins[i] 会减少混乱。还有,Do not cast the result of malloc()。另外,如果calloc()没有返回NULL,没有问题,保证AFAIK返回有效地址,实际问题是什么?
  • 你能显示运行该程序时得到的输出吗?
  • 是的,请输出,因为您在打印值指针时显然使用了运算符的&amp; 地址错误,并且您打印了指针的地址。
  • 涉及calloc()的代码看起来不错,而且C中不需要强制转换,也不建议这样做。
  • 我添加了更多信息,感谢您的帮助。

标签: c pointers memory heap-memory calloc


【解决方案1】:

我认为您的第一个 calloc 调用分配的内存不足。从您发布的调试器的屏幕截图中:

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

这只会为指针分配足够的内存,而不是结构。你可能想要

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

【讨论】:

  • 你是对的,非常感谢,它为我解决了这个问题。这是我的一个巨大的错字,让我很头疼,我不敢相信我之前没有注意到它。这一行中的 sizeof 运算符写错了,我修复了它,现在一切都按预期工作了。
【解决方案2】:

如图所示并由 Matthew Wightman 指出,第一个 calloc 不正确,特别是 sizeof 运算符。图像中的 sizeof 运算符为指向 fSpi_Mod 结构的指针类型的指针分配了空间(SpiRfid 是这种类型的变量),而我的意图是为 fSpi_Mod 结构分配空间。这是我的一个错字。

因此,改变这个:

sizeof(SpiRfid)

到这里:

sizeof(fSpi_Mod)

让它工作。这只是一种可能的解决方案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-12-29
    • 2018-12-15
    • 2016-02-14
    • 2013-10-28
    • 2010-11-16
    • 2013-04-10
    • 1970-01-01
    相关资源
    最近更新 更多