释放字符串直到空终止符

Posted

技术标签:

【中文标题】释放字符串直到空终止符【英文标题】:Freeing string untill null terminator 【发布时间】:2020-10-24 21:54:49 【问题描述】:

假设我有一个结构

struct 
foo
char *p1;
char *p2;
char *p3;
foo;

我已经分配了 struct malloc - 分配的字符串行

#include <stdlib.h>
#include <string.h>

char temp[] = "this is string"
char *allocated_temp = malloc(sizeof(temp));
strcpy(allocated_temp, temp);

struct foo bar; 
bar.p1 = strtok(allocated_temp, " ");
bar.p2 = strtok(NULL, " ");
bar.p3 = strtok(NULL, " ");

我想释放p1,而不释放p2p3 指向的其他内存。 using realloc 将不起作用,因为 p3 将首先被释放,我正在寻找一种更优雅的解决方案,而不是使用在没有第一部分的情况下将结构复制到新结构或将其他两个字符串重新分配到不同的地址。

这个问题有什么好的解决方案?

(澄清一下,当我说我想释放 p1 时,我的意思是字符串的 "this\0" 部分。

【问题讨论】:

这看起来像一个 XY 问题。为什么要释放数组的一部分? @klutt 是的,我想释放内存块的第一部分(第一个空终止符之前的部分)。什么是 XY 问题? XY 问题:meta.stackexchange.com/q/66377/374458 那么当你想忽略它的时候,为什么不直接使用p2呢? 您对strtok() 的使用不正确。 bar.p1 = strtok(allocated_temp, " "); 适合第一行,但后面的行 bar.p2 = strtok(allocated_temp, NULL); 是错误的。它们应该是bar.p2 = strtok(NULL, " "); 被解析的字符串被替换为NULL,而不是分隔符字符串。 【参考方案1】:

使用标准工具(malloc 等)无法解决您的问题。您只能释放由realloc()-ing 分配的较小大小的内存末尾。

如果你想以这种方式释放p1,你必须首先将你的数据移动到分配块的开头,更新你的指针(p2和p3),然后调用realloc()

最好的方法可能是改变你的程序,以便分别 malloc p1、p2 和 p3。

【讨论】:

如果你想以这种方式释放 p1,你必须首先将你的数据移动到分配块的开头,更新你的指针(p2 和 p3),然后调用 realloc()。 给定短输入字符串,即使这样也可能不值得开销。对realloc() 的调用可能什么都不做,因为由于对齐要求,大多数堆实现在不小于 8、16 甚至 32 字节的块中分配内存。更大的问题是必须跟踪原始指针,以便以后释放它 @AndrewHenle 同意,因此是我的最后一段。如果 OP 迫切需要释放 p1,我只是提供一个算法正确的解决方案。

以上是关于释放字符串直到空终止符的主要内容,如果未能解决你的问题,请参考以下文章

将 strncpy 转换为没有空终止符空间的字符串是不是安全?

C memset - 优雅地添加一个空终止符

如何连接字符串,但保留每个单独的空终止符?

C++ char 数组空终止符位置

使用 strlen 时如何不为空终止符添加 +1 会导致使用 send 时发送额外的垃圾字节 [关闭]

字符串不是空终止错误