C语言动态分配person结构体及char*成员赋值的正确实现方法
核心疑问解答
1. 不需要重分配结构体本身的内存
首先明确:结构体person的内存大小在编译期就已经完全确定,和name指向的字符串长度无关。结构体里存储的name是指针类型,指针本身的占用空间是固定的(32位系统4字节、64位系统8字节),不管它指向的外部字符串有多长,都不会影响结构体本身的内存占用,内存对齐机制也只会在编译期计算结构体大小,运行时不需要调整结构体的内存空间。
2. 字符串成员的正确赋值方式
你确实需要单独为name指向的字符串分配内存,不能直接写p->name = personName赋值(因为这样只是让指针指向了字符串常量的地址,后续如果要修改name内容会触发非法内存访问,而且如果原personName是栈内存的话后续会变成野指针)。
你现有的逐字符realloc的逻辑虽然勉强能运行,但性能极低,完全没有必要,标准写法有两种:
写法1:标准C兼容写法(推荐)
先计算字符串长度,一次分配足够的内存再拷贝内容:
// 先计算字符串长度,+1是为了存储末尾的'\0'结束符 size_t name_len = strlen(personName); p->name = (char*)malloc(name_len + 1); // 检查内存分配是否成功,避免空指针崩溃 if (p->name == NULL) { // 错误处理:释放已经分配的person内存后退出 free(p); perror("malloc name failed"); return; } // 拷贝字符串内容到新分配的内存 strcpy(p->name, personName);
写法2:简化写法(适用支持POSIX标准的环境)
如果你的编译器支持strdup函数(大部分常见编译器都支持,注意不属于C标准库),可以一行搞定:
p->name = strdup(personName); // 同样需要检查分配是否成功 if (p->name == NULL) { free(p); perror("strdup failed"); return; }
3. 你原有代码的问题
- 循环中直接使用
name变量,没有关联到p->name,会报未定义变量错误 - 每次循环都执行
realloc,频繁申请释放内存,性能损耗极大,完全可以先计算长度一次分配 - 没有做内存分配成功的校验,一旦内存不足会触发空指针崩溃
注意内存释放逻辑
使用完person对象后,要先释放name指向的内存,再释放结构体本身的内存,避免内存泄漏:
free(p->name); free(p);
内容的提问来源于stack exchange,提问作者randomNameGenerator
相关产品推荐
相关产品推荐

