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

C free variables used with strtok

我已经看到 post 与这个相似,但我发现了一点不同,这让我误入歧途。

我有这个代码:

char * token_one = strtok(my_buffer, " ,.-");
char * token_two = strtok(NULL, " ,.-");

free(token_one);
free(token_two);

我看到 post 人们说不应释放与 strtok 一起使用的 变量 但是为什么在执行这段代码时我得到这个:

free(token_one) 没有错误

free(token_two) 我得到“无效指针

为什么我在 free(token_one) 中没有出现错误?正确的处理方法是什么?

如果您查看 strtok() 的工作原理,就会立即清楚:

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

因此第一个 free() 调用成功,前提是您的 my_buffer 来自 malloc()。第二个失败了,因为,为什么不呢?它不是来自 malloc() 等人,因此调用 free() 是未定义的行为。

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

如果存储在数组中的字符串不是从这些字符之一开始的 " ,.-" 那么从函数 strtok 返回的指针 token_one 将与指针具有相同的值my_buffer。所以它可以用来释放分配的内存。

指针token_two指向字符串的中间。所以它的值并不指向之前分配的内存。所以这个调用之后的程序

free(token_two);

有未定义的行为。

这条语句

free(token_two);
如果从函数 strtok 的调用返回的指针 token_two 是一个空指针,

将是有效的。但在这种情况下,调用 free.

不会执行任何操作

考虑两个例子。

第一个是

#include <stdio.h>
#include <stdlib.h>

int main(void) 
{
    char *p1  = malloc( 10 );
    char *p2 = p1;

    free( p2 );

    return 0;
}

您可以使用指针p2来释放最初存储在指针p1中的地址的内存。

另一方面,如果指针p2的值指向已分配的内存

,则不能使用指针p2释放已分配的内存

此程序无效。

#include <stdio.h>
#include <stdlib.h>

int main(void) 
{
    char *p1  = malloc( 10 );
    char *p2 = p1 + 5;

    free( p2 );

    return 0;
}