使用矩阵时调用sprintf出现segfault问题求助
sprintf触发段错误的原因及修复
你代码里矩阵部分的sprintf调用触发段错误,问题出在两个地方:
- 字符串常量不能写入:你给
vparam[0]赋值了"",这是个存储在只读数据段的字符串常量,sprintf尝试往只读内存里写数据,直接触发段错误。而前面正常运行的char a[80] = ""是栈上的可写数组,两者完全不同。 - vparam的内存分配类型不匹配:
vparam被声明成char**,但你用malloc(nvparam * sizeof(char[80]))分配内存,这会导致指针类型混乱。char**指向的是char*的数组,而你分配的是char[80]的数组,内存布局不兼容,后续访问vparam[0]时逻辑就错了。
修复方案1:给vparam每个元素单独分配可写内存
这种方式更灵活,适合需要动态调整每个元素大小的场景:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { // works fine char a[80] = ""; char * b = "INTER"; char * c = "10"; sprintf(a, "%s %s", b, c); // for matrix int nvparam; char **vparam_values, **vparam_keys, **vparam; //params nvparam = 1; // 先分配存储指针的数组 vparam = (char **)malloc(nvparam * sizeof(char *)); vparam_keys = (char **)malloc(nvparam * sizeof(char *)); vparam_values = (char **)malloc(nvparam * sizeof(char *)); // 给每个vparam元素分配80字节的可写内存,初始化为空字符串 vparam[0] = (char*)malloc(80 * sizeof(char)); strcpy(vparam[0], ""); vparam_keys[0] = "ITER"; vparam_values[0] = "10"; // test printf("%s\n", vparam_keys[0]); printf("%s\n", vparam_values[0]); // 现在可以正常写入 sprintf(vparam[0], "%s %s", vparam_keys[0], vparam_values[0]); printf("%s\n", vparam[0]); // 记得释放内存,避免内存泄漏 free(vparam[0]); free(vparam); free(vparam_keys); free(vparam_values); return 0; }
修复方案2:分配连续的二维数组内存
如果需要内存连续的二维结构,可以用指向数组的指针来分配:
#include <stdio.h> #include <stdlib.h> #include <string.h> int main(int argc, char *argv[]) { // works fine char a[80] = ""; char * b = "INTER"; char * c = "10"; sprintf(a, "%s %s", b, c); // for matrix int nvparam; char **vparam_values, **vparam_keys; // 声明为指向char[80]类型的指针 char (*vparam)[80]; //params nvparam = 1; // 分配nvparam个char[80]的连续内存块 vparam = (char (*)[80])malloc(nvparam * sizeof(char[80])); vparam_keys = (char **)malloc(nvparam * sizeof(char *)); vparam_values = (char **)malloc(nvparam * sizeof(char *)); // 初始化vparam[0]为空字符串 strcpy(vparam[0], ""); vparam_keys[0] = "ITER"; vparam_values[0] = "10"; // test printf("%s\n", vparam_keys[0]); printf("%s\n", vparam_values[0]); sprintf(vparam[0], "%s %s", vparam_keys[0], vparam_values[0]); printf("%s\n", vparam[0]); // 释放内存 free(vparam); free(vparam_keys); free(vparam_values); return 0; }
内容的提问来源于stack exchange,提问作者Matheus Diógenes Andrade
相关产品推荐
相关产品推荐

