Назначение и доступ к указателю на строку внутри структуры

Я пытаюсь сохранить строку в массиве, содержащемся в структуре, и получить к ней доступ, но мне трудно. Структура выглядит следующим образом:

typedef struct {
    void **storage;
    int numStorage;
} Box;

Box инициализируется как таковой:

    b->numStorage = 1000000; // Or set more intelligently
    Box *b = malloc(sizeof(Box));
    // Create an array of pointers
    b->storage = calloc(b->numStorage,sizeof(void *));

Чтобы установить строку, я использую эту функцию:

void SetString(Box *b, int offset, const char * key)
{
    // This may seem redundant but is necessary
    // I know I could do strcpy, but made the following alternate
    // this isn't the issue
    char * keyValue = malloc(strlen(key) + 1);
    memcpy(keyValue, key, strlen(key) + 1);

    // Assign keyValue to the offset pointer
    b->storage[offset*sizeof(void *)] = &keyValue;

    // Check if it works
    char ** ptr = b->storage[offset*sizeof(void *)];

    // It does
    printf("Hashcode %d, data contained %s\n", offset, *ptr);

}

Проблема заключается в том, что я пытаюсь получить его снова с точно таким же смещением:

// Return pointer to string
void *GetString(const Box *b, int offset, const char *key)

    char ** ptr = b->storage[offset*sizeof(void *)];
    if (ptr != NULL) {
        printf("Data should be %s\n", *ptr);
        return *ptr;
    } else {
     return NULL;
    }

Возвращаемый указатель является тарабарщиной. Что может быть не так?


person Rio    schedule 24.04.2011    source источник


Ответы (3)


Вам не нужно указывать фактическое смещение памяти при доступе к массивам. Просто дайте ему индекс, и вы получите правильный элемент.

Итак, в вашем третьем блоке кода:

b->storage[offset] = keyValue;

И в вашем четвертом:

char *ptr = b->storage[offset];
if (ptr != NULL) {
    printf("Data should be %s\n", ptr);
    return ptr;
} else {
 return NULL;
}

Кроме того, во втором блоке кода уже установлено b->numStorage?

person Tim Cooper    schedule 24.04.2011

b->storage[offset*sizeof(void *)] = &keyValue;

Это сохраняет адрес локальной переменной keyValue в массиве. После завершения функции этот адрес становится недействительным. Я думаю, вы хотите:

b->storage[offset*sizeof(void *)] = keyValue;

а затем внесите соответствующие изменения при извлечении.

person Alok Singhal    schedule 24.04.2011

Разве это не:

b->storage[offset*sizeof(void *)] = &keyValue

установить storage[offset*sizeof(void*)] так, чтобы он указывал на адрес локальной переменной keyValue? т.е. больше недействителен после возврата функции

person Catamorphisms    schedule 24.04.2011