C语言生成二进制序列的char**数组返回后打印乱码原因排查
问题根因
- 指针数组内存分配大小错误
你需要存储2^g.order个二进制字符串,对应要分配size个char*类型的指针空间,但你的代码里char** D = (char**)malloc(sizeof(char*)*g.order-1);仅分配了g.order-1个指针的空间,远小于实际需要的size = pow(2, g.order),直接导致堆内存越界写入,破坏了内存结构,返回后读取自然出现乱码。 - 单条字符串内存分配不足,且未预留字符串结束符位置
C语言字符串需要以\0作为结尾标识,长度为g.order的二进制序列至少需要g.order + 1字节的存储空间,但你的代码里D[i] = (char*)malloc(g.order-1)、还有栈上的buffer/tmp/final数组大小都只有g.order-1,连存储有效二进制位都不够,更别说结束符,字符串写入时直接溢出,覆盖了其他内存区域的内容。 final数组未初始化就调用strcatstrcat会从目标字符串的\0位置开始拼接新内容,你首次使用final时没有先置0,栈上的初始值是随机垃圾数据,strcat会从随机位置开始写入,结果完全不可控。- 用浮点数函数
pow计算整数次幂存在精度风险pow是数学库的浮点数运算函数,整数场景下可能出现精度误差(比如pow(2,3)可能返回7.9999999999,转int后变成7,少算一个元素),计算2的整数次幂建议用位运算1 << g.order更安全。
修复后的参考代码
char** construireSousEnsemble(graphe g){ int size = 1 << g.order; // 位运算计算2^order,避免浮点数精度问题 // 分配size个char*指针的空间 char** D = (char**)malloc(sizeof(char*) * size); if (D == NULL) return NULL; for (int i = 0; i < size; i++){ // 每个字符串需要order位 + 1位结束符 D[i] = (char*)malloc(g.order + 1); if (D[i] == NULL) { // 内存分配失败先释放已分配的空间避免泄漏 for(int k=0; k<i; k++) free(D[k]); free(D); return NULL; } // 直接按位赋值,不需要多余的buffer拼接 for (int j = 0; j < g.order; j++){ int bin = (i >> (g.order - 1 - j)) & 1; D[i][j] = bin + '0'; // 数字转字符直接加'0'即可 } D[i][g.order] = '\0'; // 手动加字符串结束符 } return D; }
内容的提问来源于stack exchange,提问作者Baptiste Leroux
相关产品推荐
相关产品推荐

