C 我的代码会泄漏内存吗?
我有一段代码,它接受一个命令行参数,该参数由两个由冒号分隔的数字组成(例如1:8),并将其转换为相应的整数值:C 我的代码会泄漏内存吗?,c,heap,free,calloc,C,Heap,Free,Calloc,我有一段代码,它接受一个命令行参数,该参数由两个由冒号分隔的数字组成(例如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
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);
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;
}
现在,虽然只要转换的值是有效的整数,strtol()函数就可以正常工作,但如果作为命令行参数传递的数字太大,则会出现以下错误:
*** Error in `program`: free(): invalid pointer: 0x0000007fefc4077b ***
有谁能向我解释一下,为什么免费(tmp)在代码的第二个版本中似乎没有必要?最初分配的内存区域会发生什么变化?漏水吗?如果是这样,这是一个问题,还是可以像我假设的那样由另一个程序重新分配?strok不分配任何内容,strok将指针返回到提供的字符串中
free
ing此指针将使程序崩溃。Strtok的工作原理与此类似:
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);
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
调用之前提供的内存丢失 strtol
应分配给long
,而不是int。如果以后需要转换为int,请先检查范围。char*tmp=(char*)calloc(16,sizeof(char));tmp=strtok(argv[i+1],分隔符)代码>泄漏刚刚分配的内存。在空闲(tmp)中
,tmp
不再指向用calloc
分配的内存的[开头]。好的。。。将数据类型从int更改为long在代码中没有问题。我能做到。至于内存分配,我应该去掉它吗?我应该简单地声明char*tmp吗?为什么?我认为分配内存是有意义的,因为我不知道CL参数要多长时间(只是它必须适合分配的空间才能有效)。@PaulOgilvie你能详细说明一下吗?我不明白为什么会这样。strtok()的结果是否未存储在分配的内存区域中?