我有一个函数,它根据运行代码的操作系统返回一个字符串数组。
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/