微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

C - 当字符指针设置为新地址时旧数据会发生什么?

如何解决C - 当字符指针设置为新地址时旧数据会发生什么?

假设我们有一个简单的 char*,然后我们重新分配地址。

char* foo = "Hello"; // [Hello] is somewhere in the memory.
char* bar = "World"; // [World] is somewhere in the memory.
foo = bar; // 'foo' and 'bar' pointing to "World",What happen to "Hello"?

我知道“Hello”和“World”是静态的,但智能编译器是否理解这一点并为您清理内存?

-- 编辑和信息 --

根据评论,结果似乎因两件事而不同,代码和编译器优化标志。

// Example 1
// Compiler Optimization Off
char* foo = "Hello";
char* bar = "World";
foo = bar; // <-- "Hello" Still on the memory.

// Example 2
// Compiler Optimization On
char* foo = "Hello"; // <-- "Hello" never exist on binary.
char* bar = "World";
foo = bar;

// Example 3
// Compiler Optimization Off
char* foo = "Hello"; // Exist on binary because it's used on the next line
printf("%s\n",foo);
char* bar = "World";
foo = bar; // Probably "hello" still exist on memory because optimization is off.

// Example 4
// Compiler Optimization On
char* foo = "Hello"; // Exist on binary because it's used on the next line
printf("%s\n",foo);
char* bar = "World";
foo = bar; // <-- What happen to "Hello" Now?

你能解释示例 4吗?

谢谢。

解决方法

旧数据没有任何变化。事实上,规范说什么都不应该发生。 @client.command() async def log(ctx,msg): channel = client.get_channel(852610465871036416) await channel.message.send(msg) 在程序运行期间持续,即使 "Hello" 不再指向它。

,

您可以使用带有以下程序的 Godbolt.org 编译器资源管理器查看结果:

#include <stdio.h>

int main() {
    
    char* foo = "Hello"; // [Hello] is somewhere in the memory.
    char* bar = "World"; // [World] is somewhere in the memory.
    foo = bar; // 'foo' and 'bar' pointing to "World",What happen to "Hello"?
    printf("%s\n",foo);
}

没有优化,两个字符串都在二进制中。

https://godbolt.org/z/77xbxbGG4

通过 -O3 优化,Hello 不会放入二进制文件中。

https://godbolt.org/z/soeqjYGKo

请注意,这种优化之所以可行,是因为 foo 的初始值从未实际使用过。这是一个非常不切实际的例子——如果您要立即重新分配它,为什么还要初始化 foo

,

"Hello" 和 "World" 是具有静态存储持续时间的字符串文字。那就是当它们出现在程序中时,编译器将它们存储为字符数组。

所以在这些声明之后

char* foo = "Hello";
char* bar = "World";

指针 foo 和 bar 指向这些字符数组的第一个字符。

本次任务结束后

foo = bar;

字符串文字“Hello”仍然存在,但您无法访问它。

你可以在这个作业之后写下例如以下内容

foo = "Hello";

现在,根据编译器选项,编译器将分配先前使用的字符串文字的第一个字符的地址,或者它可以创建另一个具有静态存储持续时间的数组,其中包含相同的字符串“Hello”。

这就是if语句

if ( "Hello" == "Hello" )

可以被评估为逻辑真或假,具体取决于编译器选项,这些选项指定将相同的字符串文字存储为一个字符数组还是两个不同的字符数组。

通常编译器会在名为文字池的特殊内存范围中收集字符串文字。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。