You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C语言:void指针指向struct后无法正确访问成员的问题排查

问题:通过void指针访问struct成员得到0值的解决方法

我正在学习void指针与链表的相关知识,目前遇到一个问题:我有一个指向内存中struct地址的void指针,将其强制转换为对应struct类型后访问成员,得到的结果始终是0,而非预期值。

相关代码片段

访问struct成员的代码

void *data = ListGetItemAtIndex(freeList, i); // 返回void *类型指针
memoryBlock *block = (memoryBlock *) data;
printf("%ld\n\n", block->startAddress);

struct定义

typedef struct
{
    size_t startAddress;
    size_t memory;
} memoryBlock;

内存块创建函数

static memoryBlock* CreateMemoryBlockPointer(size_t startAdress, size_t size)
{
    memoryBlock block;

    block.startAddress = startAdress;
    block.memory = size;

    return malloc(sizeof(block));
}

赋值并添加到链表的代码

memoryBlock *ptr = CreateMemoryBlockPointer(StartAddress, size);

// 添加第一个元素到链表尾部
ListAddTail(freeList, ptr);

链表相关代码

  • 链表添加函数原型:
int ListAddTail(linkedList *list, void* data)
  • 链表节点赋值代码:
el->data = data;
el->next = NULL;

问题根源

问题出在CreateMemoryBlockPointer函数中:该函数在栈上创建了memoryBlock变量并完成赋值,但仅调用malloc分配了堆内存,却没有把栈上的block数据复制到这块堆内存里。最终返回的指针指向的是未初始化的堆内存,因此访问startAddress会得到0值(未初始化内存的默认值)。

修复方案

方案一:复制栈上数据到堆内存

分配堆内存后,使用memcpy将栈上已赋值的结构体复制过去:

static memoryBlock* CreateMemoryBlockPointer(size_t startAdress, size_t size)
{
    memoryBlock block;
    block.startAddress = startAdress;
    block.memory = size;

    memoryBlock *ptr = malloc(sizeof(block));
    if (ptr != NULL) {
        memcpy(ptr, &block, sizeof(block));
    }
    return ptr;
}

方案二:直接在堆上初始化struct

跳过栈上变量,直接在分配的堆内存中完成结构体成员的赋值:

static memoryBlock* CreateMemoryBlockPointer(size_t startAdress, size_t size)
{
    memoryBlock *ptr = malloc(sizeof(memoryBlock));
    if (ptr != NULL) {
        ptr->startAddress = startAdress;
        ptr->memory = size;
    }
    return ptr;
}

内容的提问来源于stack exchange,提问作者Code Cannibal

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.15 16:25:37