Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/c/62.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 我的代码会泄漏内存吗?_C_Heap_Free_Calloc - Fatal编程技术网

C 我的代码会泄漏内存吗?

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

我有一段代码,它接受一个命令行参数,该参数由两个由冒号分隔的数字组成(例如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);
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()的结果是否未存储在分配的内存区域中?