我有一段代码,它接受一个命令行参数,该参数由两个以冒号(例如1:8)分隔的数字组成,并将其转换为相应的整数值:
const char delimiter[] = ":";
int numOne = 0, numTwo = 0;
char *tmp = (char *)calloc(16, sizeof(char));
tmp = strtok(argv[i+1], delimiter);
numOne = atoi(tmp);
while (tmp != NULL) {
numTwo = atoi(tmp);
tmp = strtok(NULL, argv[i+1]);
}
free(tmp);
这段代码完全正常,但是,我了解到atoi()函数没有实现任何类型的错误处理。因此,如果提供的值太大,程序可能会以未定义的行为继续运行。
出于这个原因,我想用strtol()替换它,并尝试过这样:
const char delimiter[] = ":";
int numOne = 0, numTwo = 0;
char *end;
char *tmp = (char *)calloc(16, sizeof(char));
tmp = strtok(argv[i+1], delimiter);
numOne = strtol(tmp, &end, 10);
if (errno == ERANGE) {
printf("range error\n");
}
// ...
free(tmp);
现在,虽然只要转换后的值是有效整数,strtol()函数似乎工作正常,但是当一个太大的数字作为命令行参数传递时,我会收到以下错误:
*** Error in `program`: free(): invalid pointer: 0x0000007fefc4077b ***
有人可以向我解释,为什么在第二版代码中似乎没有必要使用free(tmp)?最初分配的内存区域会发生什么?它泄漏了吗?如果是这样,那是一个问题,还是可以简单地按照我的假设重新分配另一个程序?
答案 0 :(得分:0)
strtok没有分配任何东西,strok返回一个指向所提供字符串的指针。 free
这个指针会使程序崩溃。 Strtok的工作方式与此类似:
char* my_strtok(char* String, char Delim)
{
static char* pTerminus;
static char TerminateChar;
if (String==NULL) //continue search and return next token
{
if (pTerminus==NULL) return NULL;
*pTerminus = TerminateChar; //Restore original string
String = pTerminus+1; //Continue search right behind of last token
}
pTerminus = strchr(String, Delim); //Find end of token
if (pTerminus==NULL) return String; //Final token found
TerminateChar = *pTerminus; //back-up delimiter
*pTerminus='\0'; //Terminate found token
return String;
}
此外,之前calloc
调用提供的内存将丢失。