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

C语言结构体指针问题:如何将void指针值赋值给结构体成员避免内存错误

问题分析
  • 语法错误:struct data_t定义末尾缺少分号,C语言要求结构体定义结束必须添加分号,否则会直接触发编译错误。
  • 空指针解引用风险:调用data_create后未校验返回值是否为NULL,如果data_create因内存不足分配失败返回NULL,后续memcpy(d->data, data, size)会触发空指针访问,直接导致程序崩溃。
  • 你提到的free缺失问题需要从三个常见场景定位:
    1. 若data_create的实现符合注释描述(即同时分配了struct data_t本身的内存,以及d->data指向的size字节内存):你的代码本身的深拷贝逻辑没有问题,缺失的free属于调用方责任:如果传入data_create2的第二个参数data是调用方手动申请的堆内存,那么你在调用完data_create2后必须主动释放这块原始的data内存,否则就会出现内存泄漏。
    2. 若data_destroy的释放顺序错误:如果销毁函数先释放了struct data_t本身的内存,再尝试释放d->data指向的内存,会导致d->data的内存永远无法被释放,也会出现一次free缺失。
    3. 若data_create的实现存在缺陷:比如仅分配了struct data_t本身的内存,没有给d->data分配对应大小的内存,那么d->data是野指针,memcpy会触发非法内存访问,后续内存释放行为也会完全异常。
修正后的代码示例
// 修正结构体定义,添加分号
struct data_t{
   int datasize;
   void *data;
};

// 标准data_create实现参考
struct data_t *data_create(int size) {
   if(size < 1) return NULL;
   struct data_t *d = malloc(sizeof(struct data_t));
   if(!d) return NULL;
   d->data = malloc(size);
   if(!d->data) {
       free(d); // 分配失败时避免结构体本身内存泄漏
       return NULL;
   }
   d->datasize = size;
   return d;
}

struct data_t *data_create2(int size, void *data) {
   if(size < 1 || data == NULL)
      return NULL;

   struct data_t *d = data_create(size);
   // 新增空指针校验
   if(!d) return NULL;

   memcpy(d->data, data, size);

   return d;
}

// 标准data_destroy实现参考,避免free缺失
void data_destroy(struct data_t *d) {
   if(!d) return;
   free(d->data); // 先释放成员指向的内存
   free(d); // 再释放结构体本身
}
正确调用示例(避免内存泄漏)
int main() {
    int *src = malloc(sizeof(int));
    *src = 100;
    struct data_t *obj = data_create2(sizeof(int), src);
    free(src); // 必须主动释放原始传入的堆内存,否则就会出现free缺失

    // 业务逻辑使用obj...

    data_destroy(obj);
    return 0;
}

内容的提问来源于stack exchange,提问作者Rodrigo Lopes

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 11:36:03