#c #pointers #c99 #struct #memcpy
#c #указатели #c99 #структура #memcpy
Вопрос:
Я пытаюсь сохранить строку в массиве, содержащемся в структуре, и получить к ней доступ, но у меня возникают трудности. Структура выглядит следующим образом:
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 *)] = amp;keyValue;
// Check if it works
char ** ptr = b->storage[offset*sizeof(void *)];
// It does
printf("Hashcode %d, data contained %sn", 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 %sn", *ptr);
return *ptr;
} else {
return NULL;
}
Возвращаемый указатель является тарабарщиной. Что может быть не так?
Ответ №1:
Вам не нужно указывать фактическое смещение памяти при доступе к массивам. Просто укажите ему индекс, и вы получите правильный элемент.
Итак, в вашем третьем блоке кода:
b->storage[offset] = keyValue;
И в вашем четвертом:
char *ptr = b->storage[offset];
if (ptr != NULL) {
printf("Data should be %sn", ptr);
return ptr;
} else {
return NULL;
}
Также, во втором блоке кода, b->numStorage
уже было установлено?
Ответ №2:
b->storage[offset*sizeof(void *)] = amp;keyValue;
Это сохраняет адрес локальной переменной keyValue
в массиве. Как только функция завершается, этот адрес становится недействительным. Я думаю, вы хотите:
b->storage[offset*sizeof(void *)] = keyValue;
а затем внесите соответствующее изменение при извлечении.
Ответ №3:
Не так ли:
b->storage[offset*sizeof(void *)] = amp;keyValue
установить хранилище[offset*sizeof(void*)] таким образом, чтобы оно указывало на адрес локальной переменной KeyValue? т.е. больше не действует после возврата функции