strcpy(malloced_memory, argv)
strtok(mallocted_memory, ".")
尝试free(mallocted_memory)
。
filename = malloc(strlen(argv));
strcpy(filename, argv);
strk_ptr = malloc(sizeof(filename));
strk_ptr = strtok(filename,".");//
i++;
sprintf(in->file_name,"%s",strk_ptr);
while(strk_ptr = strtok(NULL,"."))//
{
i++;
sprintf(in->file_name,"%s.%s",in->file_name,strk_ptr);
sprintf(in->file_ext ,"%s",strk_ptr);
}
free(strk_ptr);
free(filename);
该代码存在我无法free(filename)
的问题。如果我尝试free(filename)
,请编程获取SIGTRAP
。但是计划正在发挥作用。
我想解决这个问题。我该怎么办?
答案 0 :(得分:3)
这一行:
filename = malloc(sizeof(argv));
应该是这样的:
filename = malloc(strlen(argv) + 1); /* +1 for the '\0' at the end */
if (filename == NULL) { /* take some action */ }
这一行:
strk_ptr = malloc(sizeof(filename));
仅创建内存泄漏,因为它后跟:
strk_ptr = strtok(filename,".");
你应该检查返回值:
strk_ptr = strtok(filename,".");
if (strk_ptr == NULL) { /* take some action */ }
顺便说一句,strtok()
函数返回一个指针,该指针指向在初始调用中传递的字符串内的标记(在您的示例中为filename
)。它不分配内存,因此不应释放其返回值(程序避免使用它,但这是一个常见的错误)。虽然我对strtok()
感到焦虑,但我会提到你不能(直接或间接地)将一个文字字符串传递给tokenize,因为它修改字符串和文字字符串是只读的。也就是说:strtok("sample.txt", ".")
是不行的。
最后,这种隐含条件不是很好的形式:
while (strk_ptr = strtok(NULL,".")) { ... }
更好的是:
while ((strk_ptr = strtok(NULL,".")) != NULL) { ... }
答案 1 :(得分:2)
使用strtok()
时,无需分配内存释放文件名没有问题,因为 malloc()正确分配了文件,但是还有许多其他问题和内存泄漏。 基本上你首先为 str_ptr :
分配内存strk_ptr = malloc(sizeof(filename));
此处 malloc()返回存储在 strk_ptr 中的指针。 然后你调用 strtok(),它还会在文件名中返回一个指针:
strk_ptr = strtok(filename,".");
所以你丢失了 malloc()返回的原始指针,现在 strk_ptr 指向 filename 中的某个位置。当您致电free(str_ptr)
时,您正在释放文件名内的内存。随后对free(filename)
的调用会报告错误。解决方案就是不需要为 strk_ptr 分配内存。
我写了一个有效的最小代码,向您展示如何正确使用 strtok 。请记住,在提问时,发布最小的工作代码总是更好。
int main(int argc, char **argv) {
char *strk_ptr;
char *filename = malloc(strlen(argv[0]) + 1);
strcpy(filename, argv[0]);
printf("filename = %s, size = %zu\n", filename, sizeof(filename));
// Do not malloc this
//strk_ptr = malloc(strlen(filename) + 1);
strk_ptr = strtok(filename,".");//
printf("%s\n", strk_ptr);
while( (strk_ptr = strtok(NULL,".")) )
{
printf("%s\n", strk_ptr);
}
free(filename);
return 0;
}
首先 argv 是一个char **所以如果你想复制作为输入传递的第一个参数的内容,你必须使用 argv [0] ,它始终是可执行文件名。
然后,sizeof(filename)
返回指针的大小而不是内容的大小,因为 filename 不是数组。你必须使用strlen(filename) + 1
。
strtok 在已分配的对象(文件名)内返回一个指针,这样不需要为分配内存> strk_ptr 强>
在循环中使用strtok时,请考虑采用以下方法:
for (strk_ptr = strtok(filename, "."); strk_ptr; strk_ptr = strtok(NULL, "."))
{
printf("%s\n", strk_ptr);
}
答案 2 :(得分:1)
filename = malloc(strlen(argv));
strk_ptr = malloc(sizeof(filename));
strk_ptr得到一些内存,你可以通过将strk_ptr指向文件名内存来留下悬空,然后最终双重释放文件名。
所以不要malloc strk_ptr。只需将其保留为char *,然后只留下最后的免费文件名
答案 3 :(得分:0)
strk_ptr = malloc(sizeof(filename));
strk_ptr = strtok(filename,".");//
...
free(strk_ptr);
不起作用。首先,strk_ptr
指向malloc的内存,但是指针会立即被其他一些值覆盖,所以基本上你失去了指向malloc内存的指针,因此不能{{1}那个记忆了。
编辑:
看到free
,我应该补充一点,不必须为指针变量本身分配内存。声明malloc(sizeof(filename))
使编译器隐式地为该指针分配内存(即4或8个字节)。所以你可以像任何其他变量一样直接使用指针,你不必char* strk_ptr;
那个变量的记忆。
free
或者,如果那不是你的意图,那么请注意char* strk_ptr;
strk_ptr = strtok(filename,".");
不返回字符串的长度,而只返回指针变量{{1}的大小},即通常为4或8,与字符串sizeof(filename)
指向的无关。另请参阅http://www.gnu.org/software/libc/manual/html_node/String-Length.html:
filename