在C语言中,如何生成具有非静态持续时间的字符串?

在C语言中,如何生成具有非静态持续时间的字符串?,c,string,C,String,我有一个字符串,在应用程序启动时只使用一次。普通的字符串文本,例如,“Hello”是静态的,这意味着它们只有在程序结束时才会被释放。我不想那样。它们可以提前解除分配。我怎么说,嘿,这个字符串文字不应该是静态的。应在作用域结束时解除分配它。我该怎么做?比如说, memcpy(GameDir+HomeDirLen, "/.Data", 7); “/.Data”即使在这一行代码运行很长时间之后,仍然作为文本存储在ram中。这是一种浪费,因为它只使用一次。这个答案并不符合您的具体需要。我把它留给评论

我有一个字符串,在应用程序启动时只使用一次。普通的字符串文本,例如,
“Hello”
是静态的,这意味着它们只有在程序结束时才会被释放。我不想那样。它们可以提前解除分配。我怎么说,嘿,这个字符串文字不应该是静态的。应在作用域结束时解除分配它。我该怎么做?比如说,

memcpy(GameDir+HomeDirLen, "/.Data", 7);

“/.Data”
即使在这一行代码运行很长时间之后,仍然作为文本存储在ram中。这是一种浪费,因为它只使用一次。

这个答案并不符合您的具体需要。我把它留给评论

你可以用。。。还有一个指向它的指针

char *p = (char[]){"Hello!"}; // vs char *p = "Hello!"
*p = 'C';                     //    *p = 'C'; // illegal

请参阅典型实现的

,如果您的程序包含字符串
“/.Data”
的任何位置,无论是作为文本还是作为任何持续时间的数组的初始值设定项,那么程序将在可执行文件中的某个位置包含这些字节。当程序加载时,它们将被加载(或映射)到内存中,我不知道有任何实现可以在程序退出之前释放这样的内存。所以到目前为止,其他的答案并不能真正实现你想要的

(如果数组是自动持续的,那么初始化通常是通过从匿名静态字符串复制来完成的。或者可以通过一系列立即存储指令来完成,这可能会占用更多内存。)

因此,如果您真的想确保这些字节在进程生命周期内不会占用内存,那么您必须从程序本身以外的其他地方获取它们。例如,您可以将字符串存储在文件中,打开它,然后将字符串读入
auto
malloc
ed数组。然后,当数组超出范围或
空闲时,您将真正恢复内存(当然,假设
空闲时
确实以对您有用的方式恢复内存)。如果您的系统提供,您也可以使用
mmap

另一方面,现代操作系统通常有虚拟内存。因此,如果字符串文本位于程序的只读数据部分,那么如果物理内存变紧,系统可以简单地删除该物理内存页并将其用于其他用途。如果您的程序再次尝试访问该数据,系统将分配一个新页面,并从磁盘上的可执行文件中透明地填充该页面-但如果您从未访问过该页面,则永远不会发生这种情况

当然,如果字符串实际上只有7个字节,这并没有多大帮助,因为在该内存页中会有很多其他内容(一个页面通常是4KB或附近的某个地方)。但是如果你的字符串真的很大,或者你有很多这样的字符串,那么这个效果可能和释放内存一样有效。您甚至可以使用各种特定于编译器的选项来确保将所有需要的字符串连续放置在可执行文件中,以便它们都位于相同的内存页中

我有一个字符串,在应用程序启动时只使用一次。 普通的字符串文字,例如,
“Hello”
是静态的,这意味着它们只是 程序结束时解除分配。我不想那样。他们可能是 早些时候被解除。我怎么说,嘿,就像,这个字符串 不应该是静态的。应在作用域结束时解除分配它。怎么 我会那样做吗

你不能。所有字符串文字都有静态存储持续时间,这是它们工作的唯一方式。如果程序源中有以任何方式使用的字符串文字,那么程序映像必须在程序数据中的某个位置包含文字表示的字节。如果文本出现在函数中(在您的示例中必须如此),那么每次调用函数时都需要保留表示形式以供使用。类似的情况也适用于在文件范围内的使用:在整个程序运行过程中,通常可以访问在文件范围内使用的字符串文本

例外情况是字符串文字用作具有静态存储持续时间的(其他)字符数组的初始值设定项。这样的初始化最初会导致相同数据的两个相同副本,其中最多一个副本在运行时实际可访问。单独保留文本的数据是没有用的。C没有为您指定一种方式来表示不应该保留文本,但是您的编译器可以自行决定省略不需要的副本,至少有些编译器可以这样做


编译器还可以折叠相同的字符串文本,甚至可能折叠只有相同尾部的文本,和/或执行其他节省空间的优化。而且您的编译器可能比您更善于识别何时以及如何安全地执行此类优化。

在堆栈上声明字符数组?或者
malloc
/
calloc
一个字符串的内存区域?我很好奇,为什么你会关心浪费7个字符的ram。从总体上看,这些文字字符串“浪费”的空间实在太小了,大部分时间都很麻烦。即使在三十年前的计算机上(主内存通常以千字节为单位),这通常也不是问题。@PiRocks或更好的
charstring[]=“/.Data”不在数组中浪费未使用的字节。:)答案向您展示了两种创建具有自动存储持续时间的字符串的方法(复合文字和
char
数组)。但是,正如这些答案所示,这两个都是用字符串初始化的。当然,该字符串也必须在您的程序中,并且它不会被释放。是的,这将起作用(
常量
看起来很奇怪,如
x+=(const int)42;
),这通常仍然会导致文本字符串
“Hello!”
在整个程序期间存储在内存中。它必须在t之前的某个地方