2014-11-24 3 views
0

AVL 프로그램에서 회전 기능을 구현하려고했지만 오른쪽 회전 기능이 호출 될 때 계속 seg 오류가 발생합니다. 나는 Valgrind의 테스트를 수행하고 내가 할 3 오류가 있습니다 : 그것은 초기화되지 않은 값이 있다는 오류의 두 언급AVL 트리 삽입으로 인해 Seg 폴트가 발생합니다.

==23399== 1 errors in context 1 of 3: 
==23399== Invalid read of size 4 
==23399== at 0x8048C3A: insert (avltree.c:190) 
==23399== by 0x80488B6: main (avltree.c:85) 
==23399== Address 0x3 is not stack'd, malloc'd or (recently) free'd 
==23399== 
==23399== 
==23399== 1 errors in context 2 of 3: 
==23399== Use of uninitialised value of size 4 
==23399== at 0x8048C3A: insert (avltree.c:190) 
==23399== by 0x80488B6: main (avltree.c:85) 
==23399== Uninitialised value was created by a stack allocation 
==23399== at 0x8048723: main (avltree.c:42) 
==23399== 
==23399== 
==23399== 1 errors in context 3 of 3: 
==23399== Conditional jump or move depends on uninitialised value(s) 
==23399== at 0x8048C03: insert (avltree.c:182) 
==23399== by 0x80488B6: main (avltree.c:85) 
==23399== Uninitialised value was created by a stack allocation 
==23399== at 0x8048723: main (avltree.c:42) 

은. 좌우의 서브 트리의 값을 교환하는 것과 관련이 있다고 생각 합니다만, 잘못되어있는 부분을 정확히 지적 할 수는 없습니다. 여기

오른쪽으로 회전 기능입니다 :

void rightRotate(node * y) 
{ 
    /* Assign values */ 
    node *x = y->left; 
    node *subTree = x->right; 

    /* Perform rotation */ 
    x->right = y; /* x is now root */ 
    y->left = subTree; 

    /* Update heights */ 
    y->height = max(height(y->left), height(y->right))+1; 
    x->height = max(height(x->left), height(x->right))+1; 
} 

그리고 모든 삽입 될 방법은 삽입 기능입니다 : 나는 내 회전 기능의 나머지 부분을 제거

void insert(node ** tree, node * item) 
{ 
    int balanceNum; 

    /* If no root, item is root */ 
    if(!(*tree)) { 
     *tree = item; 
     printf("Root: \n"); /*Every node seems to get printed here */ 
     (*tree)->height = 0; 
     return; 
    } 

    if(strcmp(item->key,(*tree)->key) < 0) { 
     insert(&(*tree)->left, item); 
    } 
    else if(strcmp(item->key,(*tree)->key) > 0) { 
     insert(&(*tree)->right, item); 
    } 
    else if(strcmp(item->key,(*tree)->key) == 0) { 
     (*tree)->frequency++; 
    } 

    /* Update height of ancestor node */ 
    (*tree)->height = max(height((*tree)->left), height((*tree)->right)) + 1; 
    printf("%s Height: %d\n", (*tree)->key, (*tree)->height); 

    balanceNum = balance(*tree); 

    if(balanceNum > 1 && strcmp(item->key,(*tree)->left->key) < 0) { 
     printf("Right Rotate! Balance: %d with %s\n", balanceNum, item->key); 
     rightRotate(*tree); 
    } 
} 

이 특별한 상황을 위해서. 누군가가 회전 기능에 문제가있는 부분을 지적 할 수 있습니까?

의견이나 제안을 보내 주셔서 감사합니다.

편집 : 내 코드 행 번호를 포함하도록 valgrind 게시글을 업데이트했습니다. 때마다 당신이 함수를 삽입하기 때문에

답변

0

이것은 다음과 같은 코드가 실행됩니다

if(!(*tree)) { 
     *tree = item; 
     printf("Root: \n"); /*Every node seems to get printed here */ 
     (*tree)->height = 0; 
     return; 
    } 

이유는 재귀 적으로()를 호출이 삽입됩니다.

if(strcmp(item->key,(*tree)->key) < 0) { 
    insert(&(*tree)->left, item); 
} 
else if(strcmp(item->key,(*tree)->key) > 0) { 
    insert(&(*tree)->right, item); 
} 
else if(strcmp(item->key,(*tree)->key) == 0) { 
    (*tree)->frequency++; 
} 

& (* tree) -> left는 NULL 일 수 있습니다. 현재 트리에 루트 만 있다고 가정하면 왼쪽과 오른쪽은 NULL 포인터입니다. 삽입은 if (! (* tree))를 우회하는 것으로 보입니다. 그러나 삽입 (& (* 트리) -> 왼쪽, 항목) 또는 삽입 (& (* 트리) -> 오른쪽, 항목) 중 하나를 호출합니다, 둘 다 첫 번째 매개 변수로 NULL 포인터가 있습니다.

+0

물론! 나는 특정 함수가 재귀 적으로 호출된다는 것을 잊고있다. 고마워. 다음 질문은 내 세그 폴트를 정확히 일으키는 원인이 무엇인지 실마리가 있습니까? 존재하지 않는 값을 교환하려고 할 수 있습니까? – Plaidypus

+0

insert()에서 어떤 줄과 같은 자세한 내용이 필요하다고 생각합니다. 초기화되지 않은 크기의 값을 사용하십시오. –

+0

삽입 함수의 줄 중 크기가 4 인 초기화되지 않은 줄을 어떻게 알 수 있습니까? – Plaidypus