C语言结构体指针问题:如何将void指针值赋值给结构体成员避免内存错误
问题分析
- 语法错误:
struct data_t定义末尾缺少分号,C语言要求结构体定义结束必须添加分号,否则会直接触发编译错误。 - 空指针解引用风险:调用
data_create后未校验返回值是否为NULL,如果data_create因内存不足分配失败返回NULL,后续memcpy(d->data, data, size)会触发空指针访问,直接导致程序崩溃。 - 你提到的
free缺失问题需要从三个常见场景定位:- 若
data_create的实现符合注释描述(即同时分配了struct data_t本身的内存,以及d->data指向的size字节内存):你的代码本身的深拷贝逻辑没有问题,缺失的free属于调用方责任:如果传入data_create2的第二个参数data是调用方手动申请的堆内存,那么你在调用完data_create2后必须主动释放这块原始的data内存,否则就会出现内存泄漏。 - 若
data_destroy的释放顺序错误:如果销毁函数先释放了struct data_t本身的内存,再尝试释放d->data指向的内存,会导致d->data的内存永远无法被释放,也会出现一次free缺失。 - 若
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
相关产品推荐
相关产品推荐

