[英]Segmentation fault while processing argv
此过程应将包含由逗号分隔的一组双数(例如7.2,9.5,-5.515)的字符串转换为double类型的向量。
void ToDoubleVec(int d,const char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
以下是调用它的程序片段:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
int main(int argc,char** argv)
{
...
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
...
}
调试器的输出:
40 lower = malloc(dim*sizeof(double));
(gdb) s
42 ToDoubleVec(dim,argv[2],lower);
(gdb) s
ToDoubleVec (d=2, commaSeparated=0x7fffffffe9d3 "2.3,-62.1", result=0x603010) at testPSO.c:11
11 result[0]=atof(strtok(commaSeparated,","));
(gdb) s
Program received signal SIGSEGV, Segmentation fault.
0x00007ffff77f56bb in ?? () from /lib/x86_64-linux-gnu/libc.so.6
为什么不起作用? 我确信我已为阵列分配了足够的内存,并且参数似乎也正确传递。
您可以将代码减少到这个SSCCE( 简短,自包含,正确的示例 ),当您省去#include <string.h>
时它很好地崩溃,并且在添加#include <string.h>
时不能完全编译:
segv.c: In function ‘ToDoubleVec’:
segv.c:8:5: warning: implicit declaration of function ‘strtok’ [-Wimplicit-function-declaration]
segv.c:8:20: warning: initialization makes pointer from integer without a cast [enabled by default]
segv.c:14:20: warning: assignment makes pointer from integer without a cast [enabled by default]
码:
#include <stdlib.h>
//#include <string.h>
static void ToDoubleVec(int d, const char* commaSeparated, double *result)
{
int i;
result[0] = atof(strtok(commaSeparated, ","));
for (i = 1; i < d; i++)
result[i] = atof(strtok(NULL, ","));
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
ToDoubleVec(dim, arg, lower);
}
从strtok()
这样的函数传递返回值,该函数可以将空指针直接返回到不容忍空指针的函数(如atof()
是蛮干的; 它会导致崩溃。 如果一切正确,你会好的; 如果没有,你会崩溃和燃烧。
未经检查的内存分配是一个类似的问题; 在原始内存分配之前,你甚至没有检查dim
是非零(和非负)。
#include <assert.h>
#include <string.h>
#include <stdlib.h>
static void ToDoubleVec(int d, char *commaSeparated, double *result)
{
int i;
char *number = strtok(commaSeparated, ",");
if (number != 0)
{
result[0] = atof(number);
for (i = 1; i < d; i++)
{
number = strtok(NULL, ",");
if (number != 0)
result[i] = atof(number);
}
}
}
int main(void)
{
int dim = 2;
double *lower = malloc(dim*sizeof(double));
char arg[] = "7.2,9.5,-5.515";
assert(lower != 0);
ToDoubleVec(dim, arg, lower);
}
您可以 - 并且在我所做的代码的一个版本中 - 添加错误打印以报告number
上的测试是否失败。 但崩溃是由strtok()
的隐式声明引起的,因为返回int
而不是char *
。
我试图编译你的代码,编译器警告我strtok()将char *作为输入,而不是const char *。 然后我尝试了这段代码,它运行正常:
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
void ToDoubleVec(int d, char* commaSeparated,double *result);
int main(int argc,char** argv)
{
int i,dim=atoi(argv[1]);
double *lower;
lower = malloc(dim*sizeof(double));
ToDoubleVec(dim,argv[2],lower);
for (i=0; i<dim; ++i) {
printf("%f\n", lower[i]);
}
return 0;
}
void ToDoubleVec(int d, char* commaSeparated,double *result)
{
int i;
result[0]=atof(strtok(commaSeparated,","));
for(i=1;i<d;i++)
result[i]=atof(strtok(NULL,","));
}
因此,尝试将const char *更改为char *,并检查传递给程序的输入,可能是不正确的,这可能是问题所在。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.