-3

我已经看到了与此类似的帖子,但我发现了一些让我误入歧途的不同之处。

我有这个代码:

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)?处理这个问题的正确方法是什么?

4

2 回答 2

5

如果你看看它是如何strtok()工作的,它会立即变得清晰:

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

因此,free()如果您my_buffer来自malloc(). 第二个失败了,因为,为什么不呢?它不是来自malloc()et al.,所以调用free()它是未定义的行为。

于 2019-08-28T13:35:00.580 回答
3

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

如果存储在数组中的字符串不是从该字符之一开始,则从函数返回" ,.-"的指针将具有与指针相同的值。所以它可以用来释放分配的内存。token_onestrtokmy_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;
}
于 2019-08-28T13:37:19.020 回答