递归生成LaTeX分式程序触发Stack smashing detected错误,求优化方案
解决C语言生成嵌套LaTeX分式时的栈溢出问题
问题根源
你的代码中使用了固定大小的栈上数组(left[256]、right[256]、result[1024])存储生成的LaTeX字符串,但嵌套分式的字符串长度是指数级增长的:
- step=1时,长度仅1位;
- step=6时,字符串长度已经接近1024的上限;
- step>6时,生成的字符串会超出数组容量,触发栈溢出检测(
stack smashing detected)。
解决方案:动态内存分配
改用动态内存分配来存储字符串,根据实际需要的长度分配内存,避免固定数组的限制。核心思路是:
- 先计算当前层级需要生成的字符串长度;
- 分配足够的内存;
- 递归生成子串后拼接内容;
- 用完内存后及时释放,避免泄漏。
修改后的代码
#include <stdio.h> #include <stdlib.h> #include <string.h> // 生成嵌套分式的字符串,返回动态分配的内存(需调用者释放) char* frac(int start, int step) { if (step == 1) { // 数字转字符串,分配足够内存 int len = snprintf(NULL, 0, "%d", start); char* res = malloc(len + 1); if (res) { snprintf(res, len + 1, "%d", start); } return res; } else { // 递归生成左右子串 char* left = frac(2 * start, step - 1); char* right = frac(2 * start + 1, step - 1); if (!left || !right) { // 内存分配失败,清理已分配的内存 free(left); free(right); return NULL; } // 计算当前字符串所需长度 int len = snprintf(NULL, 0, "%d+\\frac{%s}{%s}", start, left, right); char* res = malloc(len + 1); if (res) { snprintf(res, len + 1, "%d+\\frac{%s}{%s}", start, left, right); } // 释放子串的内存,避免泄漏 free(left); free(right); return res; } } int main() { int step; scanf("%d", &step); char* result = frac(1, step); if (result) { printf("%s\n", result); free(result); // 释放动态分配的内存 } else { fprintf(stderr, "内存分配失败\n"); return 1; } return 0; }
关键改动说明
- 返回动态分配的字符串:
frac函数不再接收字符数组参数,而是返回char*类型的动态内存,由调用者负责释放。 - 计算字符串长度:用
snprintf(NULL, 0, ...)获取生成字符串所需的总长度(包括终止符\0),确保分配的内存足够。 - 内存泄漏防护:递归生成的子串用完后立即释放,主函数中也会释放最终结果的内存。
- 错误处理:加入内存分配失败的检查,避免程序崩溃。
这个版本可以轻松支持step≤10的场景,甚至更大的step值(只要内存足够)。
内容的提问来源于stack exchange,提问作者Sharon mc
相关产品推荐
相关产品推荐

