2013-02-27 3 views
1

포인터 및 구조체의 응답을 얻기 위해 C의 연결된 목록 구현 작업을하고 있습니다. 여기링크 된 목록 구현의 구조 포인터

struct Node { 
    void *data; 
    struct Node *next; 
}; 

struct List { 
    struct Node *head; 
}; 

void initList(struct List *list) { 
    list->head = 0; 
} 

struct Node *addFront(struct List *list, void *data) { 
    struct Node *newNode; 
    newNode->data = data; 
    newNode->next = list->head; 
    list->head = newNode; 
    return newNode; 
} 

나는 int main() 기능에서 실행 테스트한다 : 여기 내 LL 데이터 구조에 대한 기본 코드는

int main() { 
    /* test addFront */ 
    double *data1; 
    double *data2; 
    *data1 = 10.5; 
    *data2 = 10.7; 
    struct List *newList; 
    initList(newList); 
    addFront(newList, data1); 
    printf("%s\n", newList->head->data); 
    addFront(newList, data2); 
    printf("%s\n", newList->head->data); 

    return 0; 
} 

내 문제는 printf와 출력을 인쇄되지이다. % s가 데이터 유형 (double)과 일치하지 않기 때문에 현재는 그대로 인쇄됩니다. 문자열 형식을 % d (으)로 변경하면 세그먼트 오류가 발생합니다. double 형 캐스트를 추가하면 두 번째 인수에 double * 유형이 있다고 나와 있는데, 이는 -> 표기법이 포인터를 역 참조 한 것으로 생각하기 때문에 혼란 스럽습니다.

나는 분실했습니다.

답변

1

2 printf("%f")있다 4의 malloc의 누락 :이

#include "stdlib.h" 
#include "stdio.h" 
struct Node { 
    void *data; 
    struct Node *next; 
}; 

struct List { 
    struct Node *head; 
}; 

void initList(struct List *list) { 
    list->head = 0; 
} 

struct Node *addFront(struct List *list, void *data) { 
    struct Node *newNode = malloc(sizeof(struct Node)); //### 
    newNode->data = data; 
    newNode->next = list->head; 
    list->head = newNode; 
    return newNode; 
} 
int main() { 
    /* test addFront */ 
    double *data1 = malloc(sizeof(double)); //### 
    double *data2 = malloc(sizeof(double)); //### 
    *data1 = 10.5; 
    *data2 = 10.7; 
    struct List *newList = malloc(sizeof(struct List)); //### 
    initList(newList); 
    addFront(newList, data1); 
    printf("%f\n", *(double*)newList->head->data);//### 
    addFront(newList, data2); 
    printf("%f\n", *(double*)newList->head->data);//### 
    // TODO: free()'s //### 
    return 0; 
} 
+1

좋습니다. 여전히 한 가지 문제는 printf 구문에서 역 참조 (dereferencing)입니다. 나는 -> 연산자가 이미 포인터로 구조체의 데이터를 역 참조했다. 아니면 구조체 자체를 역 참조하는 것입니까? 그렇다면 머리가 포인터가 아니기 때문에 머리 -> 데이터를 갖는 것이 잘못입니까? – user1427661

+0

'head-> data'는'(* head) .data'를합니다. 그래서 당신은 헤드 포인터를 deref'ed하고 당신의 손에'void * data'를 가지고 있습니다 (그러나'double'은 아닙니다). –

+0

수정 된 코드를 실행 했습니까? 그것은 내 컴퓨터에서 완벽하게 실행됩니다. –

3

data1data2을 메모리에 할당하지 않고 역 참조하고 있습니다. 시도 : 나는 당신이이 경우에해야한다고 생각하지는 않지만

double data1 = 10.5; 

addFront(newList, &data1); 

이 또는 당신이하는 malloc을 할 수 있습니다. 당신이 그들을 인쇄 할 때 또한

, 시도 :

printf("%f\n", *(double *)newList->head->data); 
1

당신은 문제를 해결하려고 무슨 짓을 한거야?

"assert.h"를 사용하여 어설 션이 올바른지 확인하거나 puts/exit가있는 명령문을 사용하십시오.

특히 인쇄하지 않는 것이 무엇인지, 무엇을 인쇄하고 싶은지 명확하게 알 수 없으므로 어설 션이 실패해야하며 마음에 들지 않으면 "클릭"합니다. 단계.

나는이 일을 즉시 할 수없는 이유는 내가 너와 내가 어떤 주장을하는지 모르기 때문이다. 그래서 네가 생각하는 것보다 더 오래 걸릴 것이다.

또한 위에 지적한대로 newNode에 대한 메모리를 할당하지 않으며 세그먼트 화 오류를 일으키는 임의의 메모리에 액세스하지 않습니다.

나는 그것을 고쳤다.

#include <stdlib.h> 
#include <stdio.h> 
#include <string.h> 
#include <assert.h> 

struct Node { 
    void *data; 
    struct Node *next; 
}; 

struct List { 
    struct Node *head; 
}; 

void initList(struct List **newList) 
{ 
    struct List* tmpList = 0; 

    assert(newList != 0); 
    tmpList = (struct List*)malloc(sizeof(struct List*)); 
    assert(tmpList != 0); 
    tmpList->head = 0; 
    *newList = tmpList; 
} 

void addFront(struct List* list, void* data) 
{ 
    struct Node* currNode = 0; 
    struct Node* prevNode = 0; 

    assert(list != 0); 
    assert(data != 0); 

    currNode = list->head; 
    while (currNode != 0) { 
     prevNode = currNode;   
     currNode = currNode->next; 
    } 
    if (prevNode == 0) { 
     list->head = (struct Node*)malloc(sizeof(struct Node)); 
     list->head->data = data; 
     list->head->next = 0; 
    } else { 
     prevNode->next = (struct Node*)malloc(sizeof(struct Node)); 
     prevNode->next->data = data; 
     prevNode->next->next = 0; 
    } 
} 

void test(const struct List *list) 
{ 
    const struct Node *iter; 
    assert(list != 0); 
    assert(list->head != 0); 
    iter = list->head; 

    while (iter != 0) { 
     assert(iter->data != 0); 
     printf("%f\n", *((double*)iter->data)); 
     iter = iter->next; 
    } 
} 

int main() 
{ 
    double* data1 = (double*)malloc(sizeof(double)); 
    double* data2 = (double*)malloc(sizeof(double)); 
    *data1 = 10.5; 
    *data2 = 10.7; 
    struct List* newList = 0; 

    initList(&newList); 
    assert(newList->head == 0); 
    puts("pass[0]."); 

    addFront(newList, data1); 
    assert(newList->head != 0); 
    assert(newList->head->data == data1); 
    puts("pass[1]."); 

    addFront(newList, data2); 
    assert(newList->head != 0); 
    assert(newList->head->data == data1); 
    assert(newList->head->next != 0); 
    assert(newList->head->next->data == data2); 
    puts("pass[2]."); 

    test(newList); 

    return 0; 
} 
+0

, 내가 그것을 고정 ... – Dmitry

3

당신은 당신의 double 포인터 data1data2에 대한 메모리를 할당하지 않습니다.

사실, 거의 모든 포인터에 대해 메모리를 할당하지 않은 것처럼 보입니다.

포인터는 모두 메모리의 주소를 참조합니다. 에 참조 된 구조 또는 변수를 지원하는 데 필요한 메모리를 할당하지 않습니다.

당신은

double *data1; // or any other kind of pointer 

당신이 그때 당신은 모든 역 참조 당신이 좋아하는 수

data1 = (double *) malloc(sizeof(double)); 

같은 필요가있는 경우 예를 들어

*data1 = 12.34; 

그러나없이, 당신은에 대한 포인터를 참조

캘커타의 블랙 홀. 뿐만 아니라

+0

고정 모든 잘못된 조언 :

나는 ###와 변경된 행을 표시 그리고 답안의 문법 오류. 미숙 한 사람을 오해하지 마십시오. –

+0

잘못된 모든 수정 사항을 다시 수정했습니다. –

+0

원래 할당 인'double data1 = (double *) malloc'이 맞다고 말하고 싶습니까? 'double *'을'double'에 할당합니까? 아니면 [malloc()의 반환 값을 캐스팅] (http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc)이 맞습니까? 어느 쪽도 아니었다. (sizeof 연산자의 변경은 추가적으로 개선 된 것입니다. 즉, 'data1'의 타입이 변경된 경우) –