C语言结构体char指针动态内存分配sprintf段错误求助
问题分析
- 指针判断语法错误:检查
malloc返回值的判断语句中,把相等判断符==写成了赋值符=,相当于刚申请完内存就主动把fact_table[i].str置为NULL,后续sprintf向空地址写入数据直接触发段错误。 - 字符串常量不可释放:索引0和1的
str直接赋值为字符串常量"1"的地址,这部分内存位于程序只读常量区,后续执行free操作时尝试释放常量区内存属于未定义行为,也会触发崩溃。 - 可选优化:使用
log10计算位数需要依赖数学库,编译时需额外加-lm参数,且浮点计算存在精度风险,更稳妥的做法是直接按long long的最大十进制长度(20位足够)申请内存,或者用snprintf(NULL, 0, "%lld", num)计算所需长度。
修正后的代码
#include <stdlib.h> #include <errno.h> #include <stdio.h> #include <string.h> #define LIMIT 20 struct entry { /* 表项定义 */ int n; long long int lli; char *str; }; void shout(char *m) { fprintf (stderr, "%s\n", m); exit (0); } int main (int argc, char *argv[]) { int n; int i; struct entry *fact_table; if (argc != 2) shout("参数错误"); n = atoi (argv[1]); if (n < 0) shout("n过小"); if (n > LIMIT) shout("n过大"); // 为结构体数组分配内存 fact_table = (struct entry*) malloc((n+1) * sizeof(struct entry)); if (fact_table == NULL) { shout("内存分配失败"); } // 计算阶乘 fact_table[0].n = 0; fact_table[0].lli = 1; // 0! = 1 fact_table[0].str = malloc(2 * sizeof(char)); strcpy(fact_table[0].str, "1"); fact_table[1].n = 1; fact_table[1].lli = 1; // 1! = 1 fact_table[1].str = malloc(2 * sizeof(char)); strcpy(fact_table[1].str, "1"); for (i=2; i<=n; i++) { fact_table[i].n = i; fact_table[i].lli = i * fact_table[i-1].lli; // N! = N*(N-1)! // 直接按long long最大十进制长度申请内存,避免依赖数学库 fact_table[i].str = malloc(21 * sizeof(char)); // 20位数字+1位结束符足够 if (fact_table[i].str == NULL) { // 修正为相等判断 shout("内存分配失败"); } sprintf(fact_table[i].str, "%lld", fact_table[i].lli); } // 打印阶乘表 for (i= 0; i<=n; i++) { printf ("%d %lld %s\n", fact_table[i].n, fact_table[i].lli, fact_table[i].str); } // 释放内存 for (i=0; i<=n; i++) { free(fact_table[i].str); } free(fact_table); return 0; }
内容的提问来源于stack exchange,提问作者dACEvid
相关产品推荐
相关产品推荐

