在C中从堆栈中删除字符串

时间:2013-03-01 16:18:40

标签: c string opengl stack glsl

我想将我的GLSL着色器存储在我的可执行文件中以获得整洁性,将函数内部定义的字符串加载到着色器对象中,当函数返回时,是否从堆栈中删除了字符串?我应该采取其他方式吗? (我记得读过有关资源文件的内容,但我之前从未使用过这些文件)

2 个答案:

答案 0 :(得分:2)

  

我想将我的GLSL着色器存储在我的可执行文件中以获得整洁,

对此没什么用处,但我能理解其动机。

  

将函数内部定义的字符串将它们加载到着色器对象中,当函数返回时,是否从堆栈中删除了字符串?

这取决于你如何宣布它。如果你写这样的东西:

void foo(…)
{
    char const string[] = "....";
}

字符串内存在堆栈上分配,并使用初始化字符串文字的内容进行初始化。字符串文字本身是指向可执行文件常量数据段中特定位置的指针。根据需要将数据段映射到进程地址(与可执行文件的其余部分^ 1一样。

当函数返回时,内存被“释放”;从技术上讲,它只是堆栈指针被回滚。

如果你把它写成

void bar(...)
{
    char const * string = "....";
}

变量string初始化为指向常量数据段本身的一部分,字符串文字所在的位置。没有分配内存,只有在实际访问文字所在的页面时才从磁盘读取内容。

从技术角度来看,访问字符串文字会增加与用于数据访问的mmap一样多的内存和I / O开销。事实上,可执行文件本身是mmap-ed,因此这是对mmap-ed文件的访问。


[1]在阻塞系统调用中等待很长一段时间的可执行文件最终将被换出系统内存,如果系统调用返回则会被换回。事实上,在现代操作系统中,所有系统内存都被作为块I / O缓存处理,并且进程内存分配被视为块设备的内容(这使得实现交换空间变得微不足道);没有后备块设备,作为进程内存的“缓存”变得不可替换。

答案 1 :(得分:1)

  

将函数内部定义的字符串将它们加载到着色器对象中会在函数返回时从堆栈中删除字符串吗?

是。一旦函数将控件返回给调用者,堆栈总是“弹出”。

  

我应该采取其他方式吗?

最好从文件中加载它。这样,您只能暂时占用资源(即将文件映射到虚拟内存,将其传输到设备,然后取消映射文件)。

如果这不是一个选项,那么最好在静态全局内存中定义数据,以便最终放入程序的"Data" segment。这样它就不会占用静态内存和堆栈(因为否则它必须从某个地方加载到堆栈的内存中,无论如何都可能是“数据”段)。例如:

void load_data()
{
    static const unsigned char mydata[] = { 0x01, 0x02, ... };
    /* Do something with "mydata" */
}