【问题标题】:Constant string arrays常量字符串数组
【发布时间】:2024-01-12 21:14:01
【问题描述】:

是否有可能有一个(固定的)数组将其元素存储在可执行文件的只读段中而不是堆栈中?我想出了这段代码,但不幸的是,它在添加、移动或删除项目时非常不灵活。如何验证字符串确实存储在只读段中?我试过 readelf -a file 但它没有列出字符串。

typedef struct {
        int len;
        int pos[100];
        char data[500];
} FixedStringArray;

const FixedStringArray items = {
        4,
        { 9, 14, 19, 24 },
        "LongWord1Word2Word3Word4"
} ;

char* GetItem(FixedStringArray *array, int idx, int *len) {
        if (idx >= array->len) {
                /* Out of range */
                *len = -1;
                return NULL;
        }

        if (idx > 0) {
                *len = array->pos[idx] - array->pos[idx - 1];
                return & array->data[array->pos[idx - 1]];
        }

        *len = array->pos[idx];
        return & array->data[0];
}

void PrintItem(FixedStringArray array, int idx) {
        int len;
        char *c;
        int i = 0;

        c = GetItem(&array, idx, &len);

        if (len == -1) return;

        while (i < len) {
                printf("%c", *c);
                *c++;
                i++;
        }
}

我正在考虑为每个数组自动生成一个结构并为 posdata 使用正确长度的脚本。在内存使用方面是否有任何问题? 或者创建一个结构(如上)来适应所有字符串会更好吗?

【问题讨论】:

    标签: c arrays string constants


    【解决方案1】:

    您的 C 编译器不能将任何/所有文字字符串粘贴到只读内存中(例如启用字符串池的 VC++)吗?还是您明确要求它们以这种方式顺序存储?

    【讨论】:

    • 是的,前者也可以。默认情况下,GCC 不应该对所有 const 变量都这样做吗?
    【解决方案2】:

    我不确定我是否理解你的问题,但你的意思是:

    const char * const array[] = { "LongWord1", "Word2", "Word3", "Word4" };
    

    这声明了一个指向常量字符的常量数组。

    好的,避免strlen,怎么样:

    struct Str {
        size_t len;
        char *str;
    };
    #define STR(s) { sizeof(#s) - 1, #s }
    const struct Str[] = { STR(LongWord1), STR(Word2), STR(Word3), STR(Word4) };
    

    【讨论】:

    • 好的,这确实会让事情变得更容易,但我不喜欢对字符串使用 NUL 终止。我不想依赖诸如 strlen() 之类的外部函数来获取长度,因为它也可以在编译时计算(使用 sizeof()-1)。
    • s前面的“#”是什么意思?
    • # 将宏参数转换为字符串,例如longword1 变成“longword1”。
    【解决方案3】:

    这个问题有点相关:
    String Literals

    正如所指出的,字符串文字在 ROM/RAM 中的存储取决于平台/实现,您不应该对此做出任何预测。同样使用脚本来读取和创建适当大小的数组并存储它们是非常不可取的。你最好去dynamic memory

    【讨论】:

    • 感谢您的链接。但是 ROM/RAM 的难度与我的问题有什么关系?我在运行时不写入字符串缓冲区。由于元素都是固定的,使用动态内存没有任何意义。