Назначение и доступ к указателю на строку в структуре - PullRequest
0 голосов
/ 24 апреля 2011

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

typedef struct {
    void **storage;
    int numStorage;
} 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;
    }

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

Ответы [ 3 ]

2 голосов
/ 24 апреля 2011
b->storage[offset*sizeof(void *)] = &keyValue;

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

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

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

2 голосов
/ 24 апреля 2011

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

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

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 уже установлено?

1 голос
/ 24 апреля 2011

Разве это не:

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

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

...