Note that there are some explanatory texts on larger screens.

plurals
  1. POC : Cannot access memory error, when finding recursively an AVL tree height
    primarykey
    data
    text
    <p>So i tried to implement an AVL tree in C. I use recursion for the insertions, and while i get some good results for small number of items, i get a "cannot access memory at..." at big input as shown below.</p> <p>Before i post the code. The problem seems to be in height() calculation. Used gdb and stepped through the rotations to see if anything goes wrong, but it seemed to behave well. (no uninitialized pointers, no trash remaining after changes). The avl_insert() code is kind of messy but i spent 2 days double checking it, i'm pretty sure it's correct.</p> <p>So, here goes the code :</p> <pre><code>#include &lt;stdio.h&gt; #include &lt;string.h&gt; #include &lt;stdlib.h&gt; #include &lt;ctype.h&gt; #include &lt;math.h&gt; typedef struct _avl{ long int value; int index; struct _avl *parent; struct _avl *left; struct _avl *right; } avl_node; //Allocating memory for a new node avl_node *avl_new_node(long int val, int index) { avl_node *t; t = (avl_node *)malloc(sizeof(avl_node)); t-&gt;index = index; t-&gt;parent = NULL; t-&gt;left = NULL; t-&gt;right = NULL; t-&gt;value = val; return t; } //Calculate subtree hight recursively int height(avl_node *t) { if(t == NULL) return 0; int leftH = height(t-&gt;left); int rightH = height(t-&gt;right); if(leftH &gt; rightH) return leftH + 1; else return rightH + 1; } //Pain in the butt, but works avl_node *avl_insert(avl_node *t, long int val, int index) { avl_node *ans; if(t == NULL) t = avl_new_node(val, index); else if(val &lt; t-&gt;value){ t-&gt;left = avl_insert(t-&gt;left, val, index); t-&gt;left-&gt;parent = t; if((height(t-&gt;left) - height(t-&gt;right)) == 2){ //Left Rotation if(val &lt; t-&gt;left-&gt;value){ avl_node *tmp; if(t-&gt;parent != NULL){ tmp = (t == t-&gt;parent-&gt;right)?(t-&gt;parent-&gt;right):(t-&gt;parent-&gt;left); tmp = t-&gt;left; } t-&gt;left-&gt;parent = t-&gt;parent; t-&gt;parent = t-&gt;left; t-&gt;left = t-&gt;parent-&gt;right; t-&gt;parent-&gt;right = t; if(t-&gt;left != NULL) t-&gt;left-&gt;parent = t; t = t-&gt;parent; } //Left-Right Rotation else if(val &gt; t-&gt;left-&gt;value){ avl_node *l; avl_node *lr; l = t-&gt;left; lr = t-&gt;left-&gt;right; //Additional startup rotation for the others to work correct if(lr-&gt;left != NULL){ lr-&gt;left-&gt;right = lr; lr-&gt;parent = lr-&gt;left; l-&gt;right = lr-&gt;left; l-&gt;right-&gt;parent = l; } l-&gt;parent = l-&gt;right; t-&gt;left = l-&gt;parent; t-&gt;left-&gt;parent = l; t-&gt;left-&gt;left = l; l-&gt;right = NULL; avl_node *tmp; if(t-&gt;parent != NULL){ tmp = (t == t-&gt;parent-&gt;right)?(t-&gt;parent-&gt;right):(t-&gt;parent-&gt;left); tmp = t-&gt;left; } t-&gt;left-&gt;parent = t-&gt;parent; t-&gt;parent = t-&gt;left; t-&gt;left = t-&gt;parent-&gt;right; t-&gt;parent-&gt;right = t; if(t-&gt;left != NULL) t-&gt;left-&gt;parent = t; t = t-&gt;parent; } } } else if(val &gt; t-&gt;value){ t-&gt;right = avl_insert(t-&gt;right, val, index); t-&gt;right-&gt;parent = t; if((height(t-&gt;right) - height(t-&gt;left)) == 2){ //Right Rotation if(val &gt; t-&gt;right-&gt;value){ avl_node *tmp; if(t-&gt;parent != NULL){ tmp = (t == t-&gt;parent-&gt;right)?(t-&gt;parent-&gt;right):(t-&gt;parent-&gt;left); tmp = t-&gt;right; } t-&gt;right-&gt;parent = t-&gt;parent; t-&gt;parent = t-&gt;right; t-&gt;right = t-&gt;parent-&gt;left; t-&gt;parent-&gt;left = t; if(t-&gt;right != NULL) t-&gt;right-&gt;parent = t; t=t-&gt;parent; } //Right-left Rotation else if(val &lt; t-&gt;right-&gt;value){ avl_node *r; avl_node *rl; r = t-&gt;right; rl = t-&gt;right-&gt;left; //Additional startup rotation for the others to work correct if(rl-&gt;right != NULL){ rl-&gt;right-&gt;left = rl; rl-&gt;parent = rl-&gt;right; r-&gt;left = rl-&gt;right; rl-&gt;right = NULL; r-&gt;left-&gt;parent = r; } r-&gt;parent = r-&gt;left; t-&gt;right = r-&gt;parent; t-&gt;right-&gt;parent = t; t-&gt;right-&gt;right = r; r-&gt;left = NULL; avl_node *tmp; if(t-&gt;parent != NULL){ tmp = (t == t-&gt;parent-&gt;right)?(t-&gt;parent-&gt;right):(t-&gt;parent-&gt;left); tmp = t-&gt;right; } t-&gt;right-&gt;parent = t-&gt;parent; t-&gt;parent = t-&gt;right; t-&gt;right = t-&gt;parent-&gt;left; t-&gt;parent-&gt;left = t; if(t-&gt;right != NULL) t-&gt;right-&gt;parent = t; t = t-&gt;parent; } } } return t; } int main(int argc, const char *argv[]) { int i; int v[100];// = {97, 10, 96, 109, 77, 70, 128, 64, 93, 45, 30, 65, 37, 46, 54, 30, 123, 112, 109, 49, 109}; avl_node *avlRoot; avlRoot = avl_new_node(97, 0); srand( 180 ); for(i = 1; i&lt;100; i++){ v[i] = rand()%130; } for(i=1; i &lt; 100; i++){ printf("I : %d and k : %d\n", i, v[i]); avlRoot = avl_insert(avlRoot, v[i], i); } return 0; } </code></pre> <p>I compile it with :</p> <pre><code>gcc -o c.out my_avl.c -Wall -g </code></pre> <p>Νο worthy warnings...</p> <p>Running this main i get from gdb :</p> <pre><code>Program received signal SIGSEGV, Segmentation fault. 0x000000000040066d in height (t=0x6020d0) at my_avl.c:33 33 int leftH = height(t-&gt;left); (gdb) bt 10 #0 0x000000000040066d in height (t=0x6020d0) at my_avl.c:33 #1 0x0000000000400672 in height (t=0x602730) at my_avl.c:33 #2 0x0000000000400672 in height (t=0x602550) at my_avl.c:33 #3 0x0000000000400672 in height (t=0x602430) at my_avl.c:33 #4 0x0000000000400685 in height (t=0x602730) at my_avl.c:34 #5 0x0000000000400672 in height (t=0x602550) at my_avl.c:33 #6 0x0000000000400672 in height (t=0x602430) at my_avl.c:33 #7 0x0000000000400685 in height (t=0x602730) at my_avl.c:34 #8 0x0000000000400672 in height (t=0x602550) at my_avl.c:33 #9 0x0000000000400672 in height (t=0x602430) at my_avl.c:33 (More stack frames follow...) </code></pre> <p>Running the code in another main with about 210,000 long int items, i get the following error :</p> <pre><code>Program received signal SIGSEGV, Segmentation fault. 0x0000000000401607 in height ( t=&lt;error reading variable: Cannot access memory at address 0x7fffff7fefe8&gt;) at bookstore.h:338 338 { (gdb) bt 10 #0 0x0000000000401607 in height ( t=&lt;error reading variable: Cannot access memory at address 0x7fffff7fefe8&gt;) at bookstore.h:338 #1 0x0000000000401629 in height (t=0x1855f70) at bookstore.h:341 #2 0x0000000000401629 in height (t=0x1855fa0) at bookstore.h:341 #3 0x0000000000401629 in height (t=0x1856030) at bookstore.h:341 #4 0x0000000000401629 in height (t=0x1855b50) at bookstore.h:341 #5 0x0000000000401629 in height (t=0x1855e20) at bookstore.h:341 #6 0x000000000040163c in height (t=0x1856030) at bookstore.h:342 #7 0x0000000000401629 in height (t=0x1855b50) at bookstore.h:341 #8 0x0000000000401629 in height (t=0x1855e20) at bookstore.h:341 #9 0x000000000040163c in height (t=0x1856030) at bookstore.h:342 (More stack frames follow...) </code></pre> <p>Watching the arguments of height in backtrace they seem to be repeating. I thought maybe some "parents" or "childs" are not cleared correctly during the rotations, creating an infinite loop or something, but after hours of testing i was unable find such an error in the code. I'm really badly stuck here... Thanks in advance for any help.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload