我已经看到了与此类似的帖子,但我发现了一些差异,这使我以错误的方式前进。
我有这个代码:
char * token_one = strtok(my_buffer, " ,.-");
char * token_two = strtok(NULL, " ,.-");
free(token_one);
free(token_two);
我看到人们说不应该释放与strtok 一起使用的变量的帖子,但为什么在执行此代码时我得到这个:
free(token_one)
没有错误
free(token_two)
我收到">无效指针">
为什么我在free(token_one)
中没有出错?处理这个问题的正确方法是什么?
如果你看看strtok()
是如何工作的,它就会立即变得清晰:
- 对
strtok()
的第一次调用返回给定的指针,通过将下一个分隔字符替换为 NUL 字节来修改指针指向的字符串。 - 任何后续调用(以
NULL
作为第一个参数完成(都会对之前保存的指针进行操作,该指针指向替换字符之后的指针。
因此,如果您my_buffer
来自malloc()
,则第一个free()
呼叫成功。第二个失败了,因为,好吧,为什么不应该呢?它不是来自malloc()
等人,所以调用free()
它是不确定的行为。
指针似乎my_buffer
指向动态分配的字符数组。
如果存储在数组中的字符串不是从以下字符之一开始" ,.-"
则从函数返回的指针token_one
strtok
将具有与指针my_buffer
相同的值。因此,它可用于释放分配的内存。
指针token_two
指向字符串的中间。因此,它的值不指向先前分配的内存。所以这个电话之后的程序
free(token_two);
具有未定义的行为。
此声明
free(token_two);
如果从函数的调用返回的指针token_two
strtok
为空指针,则有效。但在这种情况下,free
的调用不会执行任何操作。
考虑两个例子。
第一个是
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *p1 = malloc( 10 );
char *p2 = p1;
free( p2 );
return 0;
}
您可以使用指针p2
释放其地址最初存储在指针p1
中的内存。
另一方面,如果指针的值指向分配的内存内部,则不得使用指针p2
来释放分配的内存
此程序无效。
#include <stdio.h>
#include <stdlib.h>
int main(void)
{
char *p1 = malloc( 10 );
char *p2 = p1 + 5;
free( p2 );
return 0;
}