【发布时间】:2020-01-04 18:59:20
【问题描述】:
我编写了以下 C 函数来在分隔符中拆分字符串并返回单词编号“num_words”:
void split_string(char *string, char **result, char *delimiter, int num_words){
long unsigned int cont_len = strlen(string);
char line[cont_len];
strcpy(line, string);
int i = 0;
char *tmp;
char *p = strtok (line, delimiter);
while ((p != NULL) & (i <= num_words)){
if (i == num_words){
*result = strdup(p);
break;
}
p = strtok (NULL, delimiter);
i = i+1;
}
free(p);
}
主要是:
char *string = "hello whole world";
char *result;
char *delimiter = " ";
int num_words = 2;
split_string(string, &result, delimiter, num_words);
在本例中,split_string 将使结果等于“世界”。但是,当我尝试使用 gdb 进行调试时,我得到一个源自 split_string 函数的 free(p) 代码行的 munmap_chunk(): invalid pointer 错误。
我知道strdup 分配内存,这就是我试图释放 p 指针的原因。我应该把这个免费放在哪里?我应该只使用free(result) 吗?我已经阅读过类似 stackoverflow 问题的答案,但没有一个可以解决我的问题...
【问题讨论】:
-
您没有分配任何数据(
strtok()没有这样做),因此您不得尝试释放任何数据。free()函数只用于释放动态分配的内存,一般通过malloc/calloc/realloc获得。 -
我不是说是
strtok分配了内存,而是strdup确实分配了内存 -
对不起,我措辞不好。传递给
free()的指针值必须为空或等于先前从分配函数中获得的值,并且随后未被释放。在您尝试释放它时,p通常不满足后一个标准,即使string是 这样的函数入口处的指针。strdup()不考虑它,因为p绝不会将调用strdup()的返回值作为其值。p的值都是strtok()的返回值。 -
好的,我想我现在明白了。所以我主要只需要
free(result)?另外,如果我从split_string函数中删除free(p),它会不会出现内存泄漏?就像现在一样 -
是的,
split_string()的调用者需要负责释放通过result参数返回的指针。如果split_string自己释放了那个指针,那么调用者就不能使用它。如果程序始终释放从每次调用中获得的结果指针,则程序将不会出现与此特定函数相关的泄漏。该函数不应在任何时候尝试free(p)。
标签: c