修改结构体中的char*指针遇到问题,求解决方案
解决结构体中char*指针赋值的问题
我一眼就看出你遇到的问题根源了——你的struct labelMem里的char *name只是一个未初始化的指针,它并没有指向一块合法的内存空间!直接用strnccpy往这个指针里写数据,本质上是在往随机的内存地址上写,这会导致内存越界、程序崩溃或者各种莫名其妙的行为,属于典型的未定义行为。
下面给你两种最常用的解决方案,你可以根据自己的需求选择:
方案一:改用固定大小的字符数组(最简单直接)
既然你已经定义了MAXLINELENGTH,不如直接把char *name换成固定长度的字符数组,这样每个labelMem实例都会自带一块专属的内存空间,不用手动分配和释放,非常省心。
修改后的代码如下:
#define MAXLINELENGTH 1000 #define MAXINSTRUCTIONS 65536 struct labelMem { char name[MAXLINELENGTH]; // 替换char*为固定大小数组 int pc; }; struct labelStr { struct labelMem labels[MAXINSTRUCTIONS]; }; // 循环中的赋值代码 while (func(s) == 0) { // 复制字符串时预留一个位置存终止符 strncpy(programLabels.labels[labelCounter].name, label, MAXLINELENGTH - 1); // 手动添加字符串终止符——这一步很重要!strncpy不会自动加'\0' programLabels.labels[labelCounter].name[MAXLINELENGTH - 1] = '\0'; labelCounter++; }
方案二:手动动态分配内存(灵活但需要管理内存)
如果你的标签长度不确定,或者想节省内存空间,可以继续用char *name,但必须在赋值前手动为它分配内存,用完后还要记得释放,避免内存泄漏。
修改后的代码示例:
#define MAXLINELENGTH 1000 #define MAXINSTRUCTIONS 65536 struct labelMem { char *name; int pc; }; struct labelStr { struct labelMem labels[MAXINSTRUCTIONS]; }; // 循环中的赋值代码 while (func(s) == 0) { // 分配足够的内存,+1是为了存字符串终止符 programLabels.labels[labelCounter].name = malloc(MAXLINELENGTH); // 一定要检查内存分配是否成功! if (programLabels.labels[labelCounter].name == NULL) { perror("Failed to allocate memory for label name"); exit(EXIT_FAILURE); } // 复制字符串并手动添加终止符 strncpy(programLabels.labels[labelCounter].name, label, MAXLINELENGTH - 1); programLabels.labels[labelCounter].name[MAXLINELENGTH - 1] = '\0'; labelCounter++; } // 程序结束前记得释放所有分配的内存 for (int i = 0; i < labelCounter; i++) { if (programLabels.labels[i].name != NULL) { free(programLabels.labels[i].name); } }
额外提醒:关于strncpy的坑
strncpy的设计初衷不是用来安全复制字符串的——如果源字符串长度超过你指定的复制长度,它不会自动添加'\0',这会导致你的name变成一个没有终止符的“非法字符串”,后续用strlen、printf等函数处理时会出问题。所以无论用哪种方案,都要手动添加'\0',或者改用更安全的函数(比如strlcpy,不过它是BSD扩展,不是标准C函数)。
内容的提问来源于stack exchange,提问作者Chase
相关产品推荐
相关产品推荐

