2012-02-14 2 views
0

일부 데이터의 주소를 배열에 저장해야합니다. 모든 데이터는 "dagNode"유형의 구조입니다. 작업을 수행하기 위해 목록을 방문하고 주소를 기록 할 데이터의 수를 세어 메모리에 적절한 공간을 할당하고 마지막으로 목록을 다시 방문하여 일부 데이터의 주소를 저장합니다.구조체에 대한 포인터 배열을 사용하는 동안 세그먼테이션 오류가 발생했습니다.

struct dagNode *buildBST(struct dagNode *rootList){ 
    struct dagNode *head, **xTest; 
    head = rootList; 
    int numXtest=0; 

    rootList = nextNode(TYPE_XTEST, rootList); 

    while (!IS_TERMINATED(rootList)){ // first visit 
     numXtest++; 
     rootList = nextNode(TYPE_XTEST, rootList); } 

    xTest = (struct dagNode **) malloc(sizeof(struct dagNode) * numXtest); 
    int i=0; rootList = nextNode(TYPE_XTEST, head); 

    for(i=0; i<numXtest; i++){  // second visit, saving the address of some datas 
     rootList = nextNode(TYPE_XTEST, rootList); 
     xTest[i] = rootList; i++; 
    >>> printf("t=%d,val=%d\t", xTest[i]->nodeType, xTest[i]->val); } // segmentation fault 

    return head; 
    } 

는 편집 :

struct dagNode *nextNode(int typeOfNextNode, struct dagNode *node){ 
     if (IS_TERMINATED(node)){ return node; } 
     node = node->next; 
     if (typeOfNextNode == TYPE_EDGE_OR_GAP){ 
      while (!IS_TERMINATED(node) && !IS_AN_EDGE(node) && !IS_A_GAP(node)){ 
       node = node->next; } 
       }else 
     { 
      while (!IS_TERMINATED(node) && (node->nodeType != typeOfNextNode)){ 
       node = node->next;} 
     } 
     return node; } 
+0

우리에게'nextNode' 함수를 보여주세요. – cnicutar

+0

디버거에서 코드를 실행하여 문제를 격리 할 수 ​​있습니다. –

+3

그것은 오랜 시간 동안 본 가장 이해하기 어려운 코드 레이아웃입니다. 제발, 모든 사람들을 위해서, 좀 더 정통적인 형식을 채택하십시오. 적어도 if와 else는 수직으로 정렬되어야하고,'}'는 줄의 시작 부분에 있어야하며 끝 부분에 숨겨져 있지 않아야합니다. –

답변

1

xTest 포인터의 유형과 할당 할 크기가 malloc 사이에 일치하지 않습니다. xTest 유형 struct dagNode **의 경우, 적절한 할당해야한다 :

xTest = malloc(sizeof(struct dagNode *) * numXtest); 

아마 당신은 구조체로하지 numXtest 구조체를 numXtest 포인터를 할당 할.

2

nextNode()은 분명 범인이 될 것으로 보인다.

편집 : 또한 반복 당 두 번씩 i을 증가시킵니다. 이것은 확실히 추락 할 것이다.

+1

이것이 가장 문제가되는 원인입니다. 루프에서 숨겨진 증가분'xTest [i] = rootList; 나는 인쇄하기 바로 전에. 따라서 데이터를 인쇄하기 전에 방금 설정 한 포인터를 건너 뜁니다. 'for' 루프 컨트롤 또한'i'를 증가시키기 때문에, 당신은 (OP) 아마 루프 안에서'i ++; '를 삭제해야합니다. @Blagovest에 의해 확인 된 메모리 문제는 또한 처리해야 할 것이지만, sizeof (struct dagNode)> sizeof (struct dagNode *) (노드가 포인터를 포함하고 있기 때문에 피할 수없는) 경우, 결함은 오히려 메모리를 낭비합니다 충돌을 일으키는 것보다. –

0

죄송하지만이 게시물은 질문에 답변하지 않습니다. 나는 단지 당신에게 대안 코딩 스타일의 예를주고 싶다. 너가 좋아하는 것을 가져와.

다른 답변/설명에서 이미 지적한 가장 명백한 버그를 제거한 것을 제외하면 코드의 의미는 변경하지 않았습니다.

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

typedef struct 
{ 
    ... 
} dagNode; 

dagNode* buildBST (dagNode* rootList) 
{ 
    dagNode* head; 
    dagNode** xTest; 
    int numXtest=0; 
    int i=0; 

    head = rootList; 
    rootList = nextNode(TYPE_XTEST, rootList); 

    while (!IS_TERMINATED(rootList))    // first visit 
    { 
    numXtest++; 
    rootList = nextNode(TYPE_XTEST, rootList); 
    } 

    xTest = malloc(sizeof(dagNode) * numXtest); 
    rootList = nextNode(TYPE_XTEST, head); 

    for(i=0; i<numXtest; i++)      // second visit, saving the address of some datas 
    {  
    rootList = nextNode(TYPE_XTEST, rootList); 
    xTest[i] = rootList; 

    printf("t=%d,val=%d\t", 
      xTest[i]->nodeType, 
      xTest[i]->val); 
    } 

    return head; 
} 


dagNode *nextNode (int typeOfNextNode, dagNode *node) 
{ 
    if (IS_TERMINATED(node)) 
    { 
    return node; 
    } 

    node = node->next; 

    if (typeOfNextNode == TYPE_EDGE_OR_GAP) 
    { 
    while (!IS_TERMINATED(node) && 
      !IS_AN_EDGE(node) && 
      !IS_A_GAP(node)) 
    { 
     node = node->next; 
    } 
    } 
    else 
    { 
    while (!IS_TERMINATED(node) && 
      (node->nodeType != typeOfNextNode)) 
    { 
     node = node->next; 
    } 
    } 

    return node; 
} 
+0

게시물을 보내 주셔서 감사합니다. 향후 귀하의 (더 나은) 스타일을 따르고 있습니다. – optimusfrenk

관련 문제