如何处理C语言含未知长度字符串的struct?程序报错求助
C语言带动态字符串结构体的问题排查与修复
核心错误点:
- 返回栈内存地址导致野指针:
create_object函数中的my_object是栈上的局部变量,函数执行完毕返回后,栈帧会被销毁,返回的指针变成无效的野指针。后续对该指针的所有读写操作都是非法内存访问,这是数值异常、程序崩溃的根本原因。 - strncpy参数使用错误:
set_word和set_another_word中,strncpy的第三个参数用了sizeof((*my_object)->a_word) + 1,但(*my_object)->a_word是指针类型,sizeof得到的是指针的字节数(32位系统为4,64位为8),并非你分配的内存长度。正确的做法是使用strlen(a_word) + 1,确保完整复制字符串及终止符。 - 未释放结构体本身的内存:
clear_memory仅释放了字符串指针指向的内存,但结构体本身如果是动态分配的,最后也需要释放,否则会造成内存泄漏。
修正后的代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> typedef struct Object { unsigned short a_number; char *a_word; char *another_word; } Object; // 动态分配结构体内存并初始化成员 Object *create_object() { Object* p_my_object = malloc(sizeof(Object)); if (p_my_object == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } // 初始化指针为NULL,避免后续free时操作野指针 p_my_object->a_word = NULL; p_my_object->another_word = NULL; p_my_object->a_number = 0; return p_my_object; } void set_word(Object *my_object, const char *a_word) { // 先释放原有内存,防止重复调用时内存泄漏 if (my_object->a_word != NULL) { free(my_object->a_word); } size_t str_len = strlen(a_word) + 1; my_object->a_word = malloc(str_len); if (my_object->a_word == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } // 已分配足够空间,用strcpy更直接 strcpy(my_object->a_word, a_word); } void set_another_word(Object *my_object, const char *another_word) { if (my_object->another_word != NULL) { free(my_object->another_word); } size_t str_len = strlen(another_word) + 1; my_object->another_word = malloc(str_len); if (my_object->another_word == NULL) { perror("malloc failed"); exit(EXIT_FAILURE); } strcpy(my_object->another_word, another_word); } void set_number(Object *my_object, unsigned short a_number) { my_object->a_number = a_number; } void clear_memory(Object **my_object){ if (*my_object == NULL) { return; } // 释放字符串内存 free((*my_object)->a_word); free((*my_object)->another_word); // 释放结构体本身 free(*my_object); // 将指针置为NULL,避免悬空指针 *my_object = NULL; } int main() { unsigned short a_number = 100; const char *a_word = "apple"; const char *another_word = "banana"; Object *my_object; my_object = create_object(); set_word(my_object, a_word); set_another_word(my_object, another_word); set_number(my_object, a_number); printf("a_number: %hu\n", my_object->a_number); printf("a_word: %s\n", my_object->a_word); printf("another_word: %s\n", my_object->another_word); clear_memory(&my_object); return 0; }
修正说明:
create_object改为动态分配结构体内存,同时初始化所有成员,避免野指针问题。- 简化了
set_*函数的参数(无需双重指针,因为不需要修改结构体指针本身),修复了字符串复制的参数错误,增加了内存分配失败的错误处理,同时添加了重复调用时释放原有内存的逻辑,防止内存泄漏。 clear_memory补充了结构体本身的内存释放,并将指针置为NULL,避免后续误操作悬空指针。
内容的提问来源于stack exchange,提问作者tewerty
相关产品推荐
相关产品推荐

