c - 构造变量后使其成为常量

标签 c

我有一个函数,它根据运行代码的操作系统返回一个字符串数组。

int arrayLength = getMeThatArrayLength();
char* someArray[arrayLenth];

populateTheArray(&someArray, arrayLength);

一旦生成,数组应该是不可变的。
返回的数据在程序的整个生命周期内不应更改。

就像我将数据存储在这些变量中一样:
const int cArrayLength;
const char* const* cSomeArray;

哪里cArrayLength将举行任何arrayLength有和 cSomeArray将举行任何someArray已。

直接分配会引发错误,我明白为什么。
const int cArrayLength = arrayLength;
const char* const* cSomeArray = someArray;

也许我需要一个指向可变数组的不可变指针?我对 C 相当陌生,所以我不完全确定,但也许指针可以指向数组,但从指针的角度来看它是不可变的,并且作为保存该不可变指针的函数的扩展。

有没有办法做到这一点?

最佳答案

C 不允许您访问非 const extern/static/_Thread_local数据来自 const - 合格的声明。

你不能拥有(官方的;实际上它往往有效)一个全局性的 int arrayLength;在其他地方(在另一个翻译单元中)公开为 extern int const arrayLength; .

您可以拥有的是 static/static _Thread_local通过访问器访问的可写全局,该访问器返回指向它的指针到常量。

示例代码:

//PUBLIC HEADER
struct myvec{
    int arrayLegth;
    char const*const* someArray;
};
struct myvec const* getmyvec(void); 
/*const on structs works as if it make each memeber const:
     int const arrayLength
     char const*const*const someArray;
*/

///PRIVATE IMPLEMENTATION (in a C file that includes the header)
static struct myvec internal;
struct myvec const* getmyvec(void)
{
    if(internal.someArray) return &internal;
    //(allocate?+) fill internal ...
    return &internal;
}

访问器方法(以及官方不支持的将 int x; 暴露为 extern int const x; 的方式)依赖于类型系统。

如果它是 static/extern/_Thread_local,基础数据不会像通常(实现细节)那样位于写保护的内存中。最初声明的数据 const .这意味着您可以抛弃 const然后通过新指针写入数据。

使用系统相关机制,如 mprotect * 实际上可以将内存页标记为只读,以便稍后尝试写入它会生成段错误,但这是一个相当粗略且昂贵的操作,可能不值得——基于类型系统的保护在以下情况下可能就足够了你的用例。
mprotect程序加载器通常如何为最初声明的全局数据实现写保护 const :链接器将所有这些数据聚合到一个连续的块中,加载器将加载它,然后它会 mprotect所有这些在一个系统调用中都是只读的。

关于c - 构造变量后使其成为常量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59767722/

相关文章:

使用eclipse编译报错

c - 解除绑定(bind) sigaction 处理程序

c - 旋转慢慢缩小图像

c - 在 ncurses 中滚动数据

c++ - 如何在 Windows 7 上获取 gethostid 行为?

c++ - 六角射线转换

c - 项目配置问题如何为每个项目指定唯一的 - kwcc_config.xml?

c - 在转换不同大小的结构指针时理解内存结构

java - 用 C 和 Java 解决数字难题

c - 静态链接到C程序的Rust代码是否会因此获得任何有益的安全特性?