C 通过 char* 正确处理空终止符

标签 c memory-management memory-leaks

这个问题旨在加深我对
的理解 分配和释放时我可以对指针做什么和不能做什么:

下面的代码并不意味着要运行,而只是为下面的问题设置一个情况。

char *var1  = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));

var1 = "01234567";

var1[2] = '\0';
var1[5] = '\0';

//var1 = [0][1][\0][3][4][\0][6][7]

var2[0] = var1[0];
var2[1] = var1[3];
var2[2] = var1[6];

free(var1);
free(var2);

给出以下代码片段

1:如果您知道分配的大小,是否可以写入\0 之后的位置。

2:如果 var2 指向另一个指针所指向的 block ,我可以执行我对 var2 所做的操作吗?

3:免费电话可以吗?或者会由于 var1 中的\0 而自由死亡。
我在释放后打印出了所有变量,并且只有第一个 null 之前的变量被释放(更改为 null 或其他奇怪且正常的字符)。这样可以吗?

4:您希望指出的任何其他完全错误的内容应该避免。

非常感谢。

最佳答案

好的,让我们回顾一下您在这里所做的事情:

char *var1  = calloc(8,sizeof(char));
char **var2 = calloc(3,sizeof(char*));

因此,var1 是(指向)8 个字符的 block ,全部设置为零\0var2 是(指向)3 个指针的 block ,全部设置为 NULL。

现在它是程序的内存,它可以用它做任何它想做的事。

专门回答你的问题~

在 char block 内写入字符是很正常的。这是一种常见的编程模式,通过在一段文本后写入 \0 来对其使用日常 C 字符串操作来解析字符串缓冲区,然后指向添加的 \0 之后的下一个字符并继续解析。

var2 只是一堆字符指针,它可以指向任何需要的字符,它不一定必须位于字符串的开头。

free() 的调用有些正常(除了错误 - 见下文)。 free()d block 的内容在返回到堆栈时被覆盖是正常的,因此如果之后打印出来,它们通常看起来有“垃圾”字符。

var1 的分配存在一些问题 ~

var1 = "01234567";

这里你说的是“var1现在指向这个常量字符串”。您的编译器可能已生成有关此的警告。首先,代码将 const char* 分配给 char* (硬编码字符串是 const,但 C 编译器只会对此发出警告 [编辑:这对于 C++ 来说是正确的) ,而不是 C,请参阅 n.m. 的评论])。其次,代码丢失了对var1用来指向的内存块的所有引用。现在你永远不能free()这 block 内存了——它已经泄漏了。然而,在程序结束时,free() 尝试操作指向未在堆上分配的内存块(“01234567”)的指针。这不好。由于您立即退出,因此不会产生任何不良影响,但如果这是在执行过程中,则下一个分配(或下一个第 1000 个!)可能会奇怪地崩溃。这类问题很难调试。

也许你应该在这里做的(不过我猜你的意图)是使用字符串副本:

strncpy(var1, "01234567", 8);

通过该操作而不是赋值,一切正常。这是因为数字存储在第 1 行分配的内存中。

关于C 通过 char* 正确处理空终止符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53383804/

相关文章:

c++ - 如何删除此 Void Pointer?

ios - 找不到我的应用程序崩溃的原因

c++ - 从 C++ 中的函数返回引用的推荐方法

c++ - gRPC async_client 中的内存泄漏

c++ - 尝试用 codelite 编译

c - 打印数据并给出开始和结束

c - C 中 malloc 分配的意外大小输出

c# - 文本框是否将全数字文本保存为长文本或字符串?

java - 线程中出现异常 "main"java.lang.UnsatisfiedLinkError : no JNTIest in java. library.path

c - 如何正确循环嵌套 switch 语句以提供所示的输出?