2013-05-14 3 views
2

Я следующий код C:таНос и указатель на структуры

typedef struct DListNode_ { 
    void *data; 
    struct DListNode_ *prev; 
    struct DListNode_ *next; 
} DListNode; 


typedef struct DList_ { 
    int size; 
    DListNode *tail; 
    DListNode *head; 
} DList; 

void insert(DList * list, DListNode * element, int data) { 
    DListNode * new_element = (DListNode *)malloc(sizeof(DListNode)); 
    new_element->data = &data; 
    if (list->head==NULL) { 
     list->head=list->tail=new_element; 
     list->size++; 
     return; 
    } 
    if(element == NULL) { 
     // handle size==0? 
     new_element->next=list->head; 
     list->head->prev=new_element; 
     list->head=new_element; 
     list->size++; 
    } else { 
     printf("Not yet implemented!\n"); 
    } 
} 

void printNodes(DList *list) { 
    DListNode * pointer = list->head; 
    if (pointer!=NULL) { 
     int v= *((int*)pointer->data); 
     printf("Node has value: %d\n", v); 
     while (pointer->next != NULL) { 
      v = *((int*)pointer->data); 
      printf("Node has value: %d\n", v); 
      pointer=pointer->next; 
     } 
    } 
} 

int main(int argc, const char * argv[]) 
{ 

    int e0 = 23; 
    int e1 = 7; 
    int e2 = 11; 
    DList *list = (DList *)malloc(sizeof(DList)); 
    initList(list); 
    assert(count(list)==0); 
    insert(list, NULL, e0); 
    assert(count(list)==1); 

    insert(list,NULL, e1); 
    assert(count(list)==2); 

    insert(list,NULL, e2); 
    assert(count(list)==3); 
    printNodes(list); 

    return 0; 
} 

У меня есть несколько проблем:

  1. делает DListNode * new_element = (DListNode *) таНос (SizeOf (DListNode)); также выделяет пространство для данных, предыдущего, следующего указателя или мне нужно вручную вызвать malloc для каждого из этих указателей?
  2. Когда я печатаю содержимое указателя данных в каждом узле, все они имеют значение , хотя я вставляю 23, 7 и 11 и устанавливаю указатель данных на адрес данных int: ** new_element-> = &data; **.

(вводная учебники по C были заказаны)

EDIT:

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

// Insert data as the new head 
void insert(DList *list, DListNode *element, void *data) { 
    DListNode *new_element = malloc(sizeof(DListNode)); 
    new_element->data = data; 
    if (list->head==NULL) { 
     list->head=list->tail=new_element; 
     list->size++; 
     return; 
    } 
    if(element == NULL) { 
     new_element->next=list->head; 
     list->head->prev=new_element; 
     list->head=new_element; 
     list->size++; 
    } else { 
     printf("Not yet implemented!\n"); 
    } 
} 

В основной я:

int main(int argc, const char * argv[]) 
{ 
    int i0=7; 
    int *ip0 = malloc(sizeof(int)); 
    ip0 = &i0; 

    int i1=8; 
    int *ip1 = malloc(sizeof(int)); 
    ip1 = &i1; 

    int *ip2 = malloc(sizeof(int)); 
    int i2=44; 
    ip2 = &i2; 

    DList *list = malloc(sizeof(DList)); 
    initList(list); 
    // create some nodes 
    assert(count(list)==0); 
    insert(list, NULL, ip0); 
    assert(count(list)==1); 

    insert(list,NULL, ip1); 
    assert(count(list)==2); 

    insert(list,NULL, ip2); 
    assert(count(list)==3); 
    printNodes(list); 

    return 0; 
} 

, который выдает:

Node has value: 44 
Node has value: 44 
Node has value: 8 

, но это должно быть:

Node has value: 44 
Node has value: 8 
Node has value: 7 
+4

Вам не нужно указывать возвращаемое значение 'malloc' в программе C. –

+0

«DListNode_» - это не что иное, как сумма его полей. Нет ничего, чтобы выделить _other_, чем указатели, о которых вы говорили. – ApproachingDarknessFish

ответ

0
  1. Вам нужно вручную установить эти указатели, где они указывают с таНос. Без него они укажут на пространство, которое не имеет размер DListNode.

  2. Не указывайте данные указателем. Просто сделайте данные int (он получает автоматическое выделение), а затем просто установите data = data (данные, которые передаются в insert).

+0

'malloc', вероятно, * не * необходимо для нормальной семантики списка. Просто укажите их на существующие сущности (или NULL, если их нет). –

+1

Да, если там уже есть узел, вы правы. В противном случае, когда вы создаете узел, самым простым способом является создание этих структур из следующих указателей. – Magn3s1um

+0

Зачем вам это делать?Если у вас еще нет узла, вам нужно, чтобы указатели в списке были «NULL», не так ли? –

3
  1. malloc(sizeof(DListNode)) выделяет пространство ровно один DListNode, который по определению состоит из void* и двух DListNode указателей. Однако он не инициализирует эти указатели.

  2. Вы назначаете адрес data аргументу insert. Это указатель на временный, который недействителен после возврата insert. Поведение программы не определено. Простое решение - просто заменить void *data на int data.

+1

.. и для их инициализации может не потребоваться вызов 'malloc'. На самом деле, для нормального поведения связанных списков вы, вероятно, не будете * 'malloc'. –

+0

@CarlNorum: Я не уверен, что вы имеете в виду. Всякий раз (или: несколько раз) я реализовал связанные списки в C, я 'malloc''d каждого узла отдельно, хотя это не требуется в каждой ситуации. –

+0

Я уверен (хотя он может исправить меня, если я ошибаюсь), что ОП спрашивает, нужно ли ему еще три раза называть 'malloc' после того, как его текущая программа запросила инициализацию указателей в его структуре списка. Я просто говорю, что он, вероятно, этого не делает. –

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