2013-09-10 3 views
0

У меня есть две структуры:тип заливки пустот указатель и выделяет память

typedef struct abc { 
    unsigned int pref; 
    unsigned int port; 
    char *aRecordIp; 
    int index; 
    int count; 
}abc_t; 

typedef struct xyz { 
     abc_t *ab; 
     int index; 
     int count; 
}xyz_t; 

, и я хотел бы, чтобы достичь следующего

int Lookup (char *lookup,void *handle) { 

*handle = (xyz_t *)malloc(sizeof(xyz_t *)); 
handle->ab = (abc_t *) malloc(sizeof(abc_t *)); 
// 

} 

Я пытаюсь типаж недействительным указатель на xyz_t в основном.

Это правильно?

+2

'handle' является указатель void и не имеет информации о типе, это только адрес в памяти, поэтому вызов 'handle-> ab' не будет работать. –

+0

Я хочу напечатать набросок на xyz_t и получить доступ к ab –

+0

Есть ли какая-то особая причина, по которой вы не можете просто изменить 'Lookup', чтобы взять' xyz_t *' вместо 'void *'? –

ответ

0

В то время как литье void* на любой тип указателя является правильным, оно не обязательно в C, и оно не рекомендуется для malloc (см. Do I cast the result of malloc?).

Кроме того, вы должны указать sizeof(xyz_t), а не sieof(xyz_t*), иначе вы выделяете достаточно памяти только для указателя, а не для всей структуры.

И, конечно, вы должны назначить указатель на handle, а не на *handle. И handle должен иметь правильный указательный тип (xyz_t*).

О, и если речь идет о литье handle по xyz_t*, тогда вы можете сделать это как ((xyz_t*)handle)->ab.

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

+0

Хорошо, когда я пытаюсь выполнить handle-> ab, я получаю сообщение об ошибке: запрос для члена ab 'в чем-то не структуре или союзе ", это из-за sizeof (xyz_t *) –

+0

Это потому, что вы' handle' '' void * '. Объявите его как 'xyz_t *', поскольку он на самом деле. – Inspired

+1

Наверное, это должно быть «xyz_t **», чтобы быть полезным. –

0

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

int Lookup (char *lookup, xyz_t **handle) { // double indirection here 

    *handle = (xyz_t *)malloc(sizeof(xyz_t)); 
    (*handle)->ab = (abc_t *) malloc(sizeof(abc_t)); 
} 

И называть это так:

xyz_t *myhandle; 
char lookup; 
Lookup(&lookup, &mynandle); 

// now you can use it 
myhandle->index ... 

Вам нужно будет освободить память, а также ...

free(myhandle->ab); 
free(myhandle); 
+0

Есть ли способ, по которому я все еще мог бы держать дескриптор как void * и выводить его в xyz_t в Lookup()? –

+0

Какова польза, на ваш взгляд, сохранения 'void *'? Это как небезопасно, как черт! –

+0

, потому что дескриптор, который передается, является указателем на пустоту. Итак, вот что, если я сохраню функцию, как вы предложили, как мне отправить на нее дескриптор void *. Ex: Я хочу, чтобы достичь чего-то вроде этого 'аннулируются * myhandle;' 'символ поиска,' 'Lookup (& поиск, & mynandle);' –

1

Вы делаете это неправильно по нескольким пунктам:

  1. Вы пытаетесь установить переменную handle->ab, но handle - это void *, а не указатель типа структуры.
  2. Вам нужно показать свой звонок, но могут возникнуть проблемы - почему вы думаете, что аргумент void * - хорошая идея?
  3. Вы хотите выделить структуры, поэтому операнды sizeof() должны быть xyz_t, а не xyz_t *; повторите для abc_t.

Вы, вероятно, следует использовать:

int Lookup(const char *lookup, xyz_t **handle) 
{ 
    ... 
    *handle = (xyz_t *)malloc(sizeof(xyz_t)); 
    (*handle)->ab = (abc_t *)malloc(sizeof(abc_t)); 
    ... 
} 

Не забудьте проверить результат malloc().

Есть те, кто заманит вас за использование бросков на malloc(). Я не буду.Когда я узнал C (давным-давно, задолго до того, как был стандарт C), на машине, где значение int * для адреса не было таким же битовым шаблоном, как адрес char * для того же места в памяти, где должно было быть malloc() объявленный char *malloc(), или весь ад сломался, броски были необходимы. Но - и это главная проблема, которую беспокоят люди. Очень важно, чтобы вы компилировали с такими параметрами компилятора, чтобы при вызове функции без прототипа в области видимости вы получили ошибку компиляции или предупреждение о том, что вы обратите внимание. Вызывает беспокойство то, что если у вас нет объявления для malloc() в области видимости, вы получите неверные результаты от использования литого, который компилятор будет диагностировать, если вы этого не сделаете.

В целом, я думаю, вам следует отделить свой код поиска от кода «create xyz_t» - ваша функция выполняет два задания, и это усложняет интерфейс вашей функции.

xyz_t *Create_xyz(void); 
int Lookup(const char *lookup, const xyz_t *handle); 
+0

Есть ли способ, где я мог еще держать ручку, как void * и вывести его в xyz_t в Lookup()? –

0

Если вы хотите передать недействительным *, вот решение

INT Lookup (символ * поиск, аннулируются * ручка) {

handle = malloc(sizeof(xyz_t)); 
((xyz_t *)handle)->ab = (abc_t *) malloc(sizeof(abc_t)); 
// 

}

Смежные вопросы