C语言结构体指针数组赋值触发segmentation fault的原因与解决方法
错误诱因
- 内存分配逻辑错误:你使用C标准库的
malloc分配包含C++std::string类型的结构体内存,malloc仅分配原始内存空间,不会调用std::string的构造函数,导致message成员处于未初始化的非法状态,直接赋值会触发非法内存访问。 - 字符串拼接逻辑错误:C/C++中双引号包裹的字符串字面量是
const char*类型,直接和整数i相加执行的是指针偏移操作而非字符串拼接。当i的数值大于字符串字面量"message"的长度(7个字符)时,指针会偏移到该字符串字面量的合法内存范围外,访问非法地址触发段错误。
修复方案
方案1:使用C++语法实现(推荐)
抛弃C的malloc,改用C++的new关键字分配内存,new会自动调用结构体及std::string成员的构造函数,同时使用std::to_string将整数转为字符串完成拼接:
#include <string> struct Data { int id; std::string message; }; Data *stack[10]; for(int i=0; i<10; i++){ stack[i] = new Data(); stack[i]->id = i; stack[i]->message = "message" + std::to_string(i); } // 程序结束前记得释放内存避免泄漏 for(int i=0; i<10; i++){ delete stack[i]; }
方案2:使用纯C语法实现
如果需要兼容C环境,把结构体中的std::string替换为char*类型,使用C标准库的字符串操作函数完成赋值:
#include <stdio.h> #include <stdlib.h> #include <string.h> struct Data { int id; char* message; }; struct Data *stack[10]; for(int i=0; i<10; i++){ stack[i] = (struct Data*)malloc(sizeof(struct Data)); stack[i]->id = i; // 构造目标字符串 char buf[20]; sprintf(buf, "message%d", i); // 为message分配内存并拷贝内容 stack[i]->message = (char*)malloc(strlen(buf) + 1); strcpy(stack[i]->message, buf); } // 程序结束前先释放成员内存,再释放结构体内存 for(int i=0; i<10; i++){ free(stack[i]->message); free(stack[i]); }
内容的提问来源于stack exchange,提问作者Zahzah
相关产品推荐
相关产品推荐

