Постоянные строковые массивы - PullRequest
7 голосов
/ 29 ноября 2009

Возможно ли иметь (фиксированный) массив, который хранит свои элементы в доступном только для чтения сегменте исполняемого файла, а не в стеке? Я придумал этот код, но, к сожалению, он очень негибкий, когда речь идет о добавлении, перемещении или удалении элементов. Как проверить, что строки действительно хранятся в сегменте только для чтения? Я попытался readelf -a файл , но в нем нет строк.

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++;
        }
}

Я рассматриваю сценарий, который автоматически генерирует структуру для каждого массива и использует правильную длину для pos и data . Есть ли какие-либо проблемы с точки зрения использования памяти? Или было бы лучше создать одну структуру (как выше), чтобы она соответствовала всем строкам?

Ответы [ 3 ]

26 голосов
/ 29 ноября 2009

Я не уверен, что понимаю ваш вопрос, но вы имеете в виду:

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) };
1 голос
/ 29 ноября 2009

Не может ли ваш компилятор C вставить / все литеральные строки в постоянную память (например, VC ++ с включенным пулированием строк)? Или вы явно требуете их последовательного хранения таким образом?

0 голосов
/ 29 ноября 2009

Этот вопрос несколько актуален:
Строковые литералы

Как указывалось, хранение строковых литералов в ПЗУ / ОЗУ зависит от платформы / реализации, вам не следует делать какие-либо прогнозы на этот счет. Также использование сценария для чтения и создания массива соответствующих размеров и их хранения является совершенно нежелательным. Вам лучше пойти на динамическую память .

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...