与 strtok 一起使用的 C 自由变量



我已经看到了与此类似的帖子,但我发现了一些差异,这使我以错误的方式前进。

我有这个代码:

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()是如何工作的,它就会立即变得清晰:

  1. strtok()的第一次调用返回给定的指针,通过将下一个分隔字符替换为 NUL 字节来修改指针指向的字符串。
  2. 任何后续调用(以NULL作为第一个参数完成(都会对之前保存的指针进行操作,该指针指向替换字符之后的指针。

因此,如果您my_buffer来自malloc(),则第一个free()呼叫成功。第二个失败了,因为,好吧,为什么不应该呢?它不是来自malloc()等人,所以调用free()它是不确定的行为。

指针似乎my_buffer指向动态分配的字符数组。

如果存储在数组中的字符串不是从以下字符之一开始" ,.-"则从函数返回的指针token_onestrtok将具有与指针my_buffer相同的值。因此,它可用于释放分配的内存。

指针token_two指向字符串的中间。因此,它的值不指向先前分配的内存。所以这个电话之后的程序

free(token_two);

具有未定义的行为。

此声明

free(token_two);

如果从函数的调用返回的指针token_twostrtok为空指针,则有效。但在这种情况下,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;
}

最新更新