Passed pointer becomes 0x1 - c

I'm working on a school assignment and am stuck on this part. To summarize what the code is supposed to do, it is meant to put 100 random integers into a B-Tree and print out the sorted list of numbers. I get my random numbers easily enough and begin to insert them using the following function:
void BTree_Insert(BTREE* tree, int* dataInPtr) {
bool taller;
NODE* newPtr;
ENTRY upEntry;
if (tree->root == NULL) {
if (newPtr = (NODE*)malloc(sizeof(NODE))) {
newPtr->firstPtr = NULL;
newPtr->numEntries = 1;
newPtr->entries[0].dataPtr = dataInPtr;
newPtr->entries[0].rightPtr = NULL;
tree->root = newPtr;
(tree->count)++;
for (int i = 1; i < ORDER - 1; i++) {
newPtr->entries[i].dataPtr = NULL;
newPtr->entries[i].rightPtr = NULL;
}
return;
}
else {
printf("Overflow error 100 in BTree_Insert\a\n"), exit(100);
}
}
taller = _insert(tree, tree->root, dataInPtr, &upEntry);
if (taller) {
newPtr = (NODE*)malloc(sizeof(NODE));
if (newPtr) {
newPtr->entries[0] = upEntry;
newPtr->firstPtr = tree->root;
newPtr->numEntries = 1;
tree->root = newPtr;
}
else {
printf("Overflow error 101\a\n"), exit(100);
}
}
(tree->count)++;
return;
}
The first number enters fine (tree->root would be null at this point), but when the second number is inserted, it calls _insert, which is where my problems start. Here is the code for _insert:
bool _insert(BTREE* tree, NODE* root, int* dataInPtr, ENTRY* upEntry) {
if (root == 0x1) {
//printf("root is now 0x1");
}
int compResult;
int entryNdx;
bool taller;
NODE* subtreePtr;
if (!root) {
(*upEntry).dataPtr = dataInPtr;
(*upEntry).rightPtr = NULL;
return true;
}
entryNdx = _searchNode(tree, root, dataInPtr);
compResult = tree->compare(dataInPtr, root->entries[entryNdx].dataPtr);
if (entryNdx <= 0 && compResult < 0) {
subtreePtr = root->firstPtr;
}
else {
subtreePtr = root->entries[entryNdx].rightPtr;
}
taller = _insert(tree, subtreePtr, dataInPtr, upEntry);
if (taller) {
if (root->numEntries >= ORDER - 1) {
_splitNode(root, entryNdx, compResult, upEntry);
taller = true;
}
else {
if (compResult >= 0) {
_insertEntry(root, entryNdx + 1, *upEntry);
}
else {
_insertEntry(root, entryNdx, *upEntry);
}
(root->numEntries)++;
taller = false;
}
}
return taller;
}
When passing through root, it for some reason becomes 0x1 and I get a read access violation. I have verified that in BTree_Insert tree->root is not 0x1, so I really have no idea what's going on. Any insight as to how to fix this would be much appreciated.

Related

doubly linked list problem with removal and push back maybe

In the main function, I tried to push front couple numbers and push back couple numbers and then remove pos = 0 and pso = 1. However, in the output, remove at pos = 0 and remove at pos = 1 prints out number 5 and number 7 which are wrong. It should be 4 and 2. I cannot find which part I am wrong. Here is my code:
#ifndef MYDLL_H
#define MYDLL_H
#include <stdlib.h>
typedef struct node
{
int data;
struct node *next;
struct node *previous;
} node_t;
typedef struct DLL
{
int count;
node_t *head;
node_t *tail;
} dll_t;
dll_t *create_dll()
{
dll_t *myDLL = (dll_t*)malloc(sizeof(dll_t));
if (myDLL == NULL) {
return NULL;
}
myDLL->count = 0;
myDLL->head = NULL;
myDLL->tail = NULL;
return myDLL;
}
int dll_empty(dll_t *l)
{
if (l == NULL) {
return -1;
}
if (l->count == 0 && l->head == NULL) {
return 1;
} else {
return 0;
}
}
int dll_push_front(dll_t *l, int item)
{
if (l == NULL) {
return -1;
}
node_t* new = (node_t*)malloc(sizeof(node_t));
if (new == NULL) {
return -1;
}
new->data = item;
new->next = l->head;
new->previous = NULL;
if (l->head != NULL) { //set new prev for the previous head before pushing.
l->head->previous = new;
}
l->head = new; // reset the new head for l.
l->count++;
return 1;
}
int dll_push_back(dll_t *l, int item)
{
if (l == NULL) {
return -1;
}
node_t* new = (node_t*)malloc(sizeof(node_t));
if (new == NULL) {
return -1;
}
new->data = item;
new->previous = l->tail;
new->next = NULL;
if(l->tail != NULL) {
l->tail->next = new;
} else {
l->head = new;
}
l->tail = new;
l->count++;
return 1;
}
int dll_pop_front(dll_t *t)
{
if (t == NULL || t->head == NULL) {
return -1;
}
node_t* pop_pointer = t->head;
int pop_item = pop_pointer->data;
t->head = pop_pointer->next; // set new head.
if (t->head != NULL) {
t->head->previous = NULL;
} else { // t->head = NULL cuz only one item and after popping, the t->head is null.
t->tail = NULL; // else if t->head = NULL, then t->tail also should be NULL.
}
if (t->head == NULL) {
t->tail = NULL;
}
t->count--;
free(pop_pointer);
return pop_item;
}
int dll_pop_back(dll_t *t)
{
if (t == NULL || t->head == NULL) {
return -1;
}
node_t* pop_pointer = t->tail;
int pop_item = pop_pointer->data;
t->tail = pop_pointer->previous;
if (t->tail != NULL) {
t->tail->next = NULL;
} else {
t->head = NULL;
}
if (t->head == NULL) {
t->tail = NULL;
}
t->count--;
free(pop_pointer);
return pop_item;
}
int dll_insert(dll_t *l, int pos, int item)
{
if (l == NULL) {
return -1;
}
if (pos >= l->count || pos < 0) {
return 0;
}
node_t* new = (node_t*)malloc(sizeof(node_t));
if (new == NULL) {
return 0;
}
new->data = item;
if(pos == 0) {
return dll_push_front(l, item);
}
node_t* pointer = l->head;
for (int i = 0; i < pos - 1; i++) {
pointer = pointer->next;
}
//ex: pos = 1, no for loop, pointer still head.
new->previous = pointer;
new->next = pointer->next;
pointer->next->previous = new;
pointer->next = new;
l->count++;
return 1;
}
int dll_get(dll_t *l, int pos)
{
if (l == NULL) {
return -1;
}
if (pos < 0 || pos >= l->count) {
return 0;
}
node_t* pointer = l->head;
for (int i = 0; i < pos - 1; i++) {
pointer = pointer->next;
}
return pointer->data;
}
int dll_remove(dll_t *l, int pos)
{
if (l == NULL) {
return -1;
}
if (pos < 0 || pos >= l->count) {
return 0;
}
node_t* pointer = l->head;
node_t* prev = NULL; // first node prev is null.
for (int i = 0; i < pos; i++) {
prev = pointer;
pointer = pointer->next;
}
if (prev == NULL) { // first item.
l->head = pointer->next;
} else {
prev->next = pointer->next;
}
if (pointer->next != NULL) {
pointer->next->previous = prev;
}
// if we are removing the tail node
if (pointer == l->tail) {
l->tail = prev;
}
int removed_value = pointer->data;
free(pointer);
l->count--;
return removed_value;
}
int dll_size(dll_t *t) {
if (t == NULL) {
return -1;
}
return t->count;
}
void free_dll(dll_t *t)
{
if (t == NULL) {
return;
}
if (t == NULL) {
free(t);
return;
}
node_t* pointer = t->head;
while(pointer != NULL) {
node_t* pointer2 = pointer;
pointer = pointer->next;
free(pointer2);
}
free(t);
}
#endif

Enqueue function of queue using linked list in c

I'm having a problem when using linked list to build a queue program. Here's the full code.
#define _CRT_SECURE_NO_WARNINGS
#include <stdio.h>
#include <stdlib.h>
#define ERROR_VALUE -300000
typedef struct LinkedNode {
int data;
struct LinkdedNode* link;
}Node;
Node* front;
Node* rear;
void init_queue() { front = rear = NULL; }
int is_empty() { return (front = NULL && rear == NULL); }
int size() {
Node* p;
int count = 0;
if (is_empty())
return 0;
for (p = front; p != rear; p = p->link) {
count++;
return count + 1;
}
}
void enqueue(int e) {
Node* p = (Node*)malloc(sizeof(Node));
p->data = e;
p->link = NULL;
if (is_empty())
front = rear = p;
else {
rear->link = p;
rear = p;
}
}
int dequeue() {
Node* p = front;
int e;
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
else if (size() == 1) {
front = rear = NULL;
}
else
front = p->link;
e = p->data;
free(p);
return e;
}
int peek() {
if (is_empty()) {
printf("Queue Empty Error!\n");
return ERROR_VALUE;
}
return front->data;
}
void print_queue() {
Node* p;
printf("QUEUE STATUS: size=%d\n", size());
if (is_empty())
return;
for (p = front; p != NULL; p = p->link)
printf("[%2d] ", p->data);
printf("\n");
}
int main(void) {
int val, sel;
init_queue();
while (1) {
do {
printf("1.ENQUEUE 2.DEQUEUE 3.PEEK 4.STATUS 0.EXIT :");
scanf("%d", &sel);
} while (sel < 0 || sel > 4);
if (sel == 1) {
printf("1.ENQUEUE VALUE ? ");
scanf("%d", &val);
enqueue(val);
}
else if (sel == 2) {
val = dequeue();
if (val != ERROR_VALUE)
printf("2.DEQUEUE VALUE = %d\n", val);
}
else if (sel == 3) {
val = peek();
if (val != ERROR_VALUE)
printf("3.PEEK VALUE = %d\n", val);
}
else if (sel == 4)
print_queue();
else if (sel == 0) break;
}
return 0;
}
I didn't made is_full() function because linked list is "dynamic". When debugging, the program stops when I try enqueuing value. My guess is that there is something wrong in enqueue function, but cannot find what.
This is wrong:
int is_empty() { return (front = NULL && rear == NULL); }
Note the front = NULL. That means every time you call is_empty(), front gets set to NULL, which then causes is_empty() to return 0 because front = NULL evaluates to NULL.
You need to change is_empty() to
int is_empty() { return (front == NULL && rear == NULL); }
And this is exactly why many programmers use "Yoda conditions" like NULL == front - they prevent this type of bug because if you write = instead of == the code will fail to compile.
And, as you've noticed, such bugs are very hard to spot in your own code.

c recursive binary

I understand the "rules" of inserting
void printTree(BTNode* node) {
if (node == NULL)
return;
printTree(node->left);
printf("%c", node->item);
printTree(node->right);
}
in createExp, the right node may be build with some chars already parsed by the left node. It will happened each time the left node parses more than one char.
To prevent this, createExp should return an info to where parsing ends. Something like this :
char *createExpTree(BTNode** root, char* prefix)
{
if (*prefix) {
if (!isdigit(*prefix)) {
*root = malloc(sizeof(BTNode));
(*root)->item = *prefix;
(*root)->left = NULL;
(*root)->right = NULL;
}
else {
*root = malloc(sizeof(BTNode));
(*root)->item = *prefix;
(*root)->left = NULL;
(*root)->right = NULL;
return prefix;
}
}
prefix = createExpTree(&(*root)->left, ++prefix);
return createExpTree(&(*root)->right, ++prefix);
}
If you need to keep createExpTree signature, you can flatten the recursion into an loop like that :
void createExpTree(BTNode** root, char* prefix)
{
BTNode** stack[SIZE];
int stackPosition = 0;
while (*prefix) {
*root = malloc(sizeof(BTNode));
(*root)->left = NULL;
(*root)->right = NULL;
if (isdigit(*prefix)) {
(*root)->item = *prefix++;
if (stackPosition == 0) break;
root = stack[--stackPosition];
}
else {
(*root)->item = *prefix++;
stack[stackPosition++] = &(*root)->right;
root = &(*root)->left;
}
}
}

NULL assignment to a structure pointer is not working through function. What to do?

I am trying to implement BST deletion. According to algorithm, we can delete a leaf directly. Now I'm assigning NULL to leaf directly and still this node remains as it is.
In the test case I gave tried to delete leaf and it is not working.
Please help!
struct node * delet(long data, struct node* root)
{
int i=1;
struct node *temp = root,*t;
while(temp != 0)
{
if(data < temp->data)
{
i=2*i;
temp = temp->l;
}
else if(data > temp->data)
{
i = (2*i)+1;
temp = temp->r ;
}
else
{
printf("%d\n",i);
break;
}
}
if(temp->l == 0 && temp->r == 0)
{
temp = 0;
return root;
}
else if(temp->l == 0)
{
temp->data = temp->l->data;
temp->l = 0;
}
else if(temp->r == 0)
{
temp->data = temp->r->data;
temp->r = 0;
}
else
{
t = temp;
t = t->r;
while(t->l != 0)
{
t = t->l;
}
temp->data = t->data;
if(t->r != 0)
{
t->data = t->r->data;
t->r = 0;
return root;
}
else
{
t = 0;
return root;
}
}
}
temp = 0; doesn't delete the leaf from the tree, just nulls a local variable.
You want to null some node's l or r in order to remove a node from the tree.
Try keeping the parent as well and once temp points to the leaf, nullify temp's parent r or l.
Same goes for t = 0; later on.
Note David's comment about first releasing this memory..
For example (assuming not deleting the root):
...
if(data < temp->data)
{
i=2*i;
parent = temp;
temp = temp->l;
}
else if(data > temp->data)
{
i = (2*i)+1;
parent = temp;
temp = temp->r ;
}
else
{
printf("%d\n",i);
break;
}
...
if(temp->l == 0 && temp->r == 0)
{
if (parent->l == temp)
parent->l = 0;
else
parent->r = 0;
// Free temp if needed
return root;
}
...
Also note that you have:
else if(temp->l == 0)
{
temp->data = temp->l->data;
Which is a dereference of a null pointer (temp->l is NULL), and the same thing for temp->r == 0 case.
Then you have
temp->l = 0;
but you're already in a temp->l == 0 case, so I don't think this is what you meant.

Corrupted Heap error c

I am trying to create a tree from a vector of parents. However I get a "corrupted heap error" when I create the nodes with malloc. It works for the first two children , however crashes on the third(or terminates but does not connect the root with the child.)
Unhandled exception at 0x77E8A879 (ntdll.dll) in lab7.exe: 0xC0000374:
A heap has been corrupted (parameters: 0x77EC5910).
I have implemented this by, first extracting the root and creating the node and after that extracting the children of the root and creating them.
search root-> searches for the root and returns the value of it.
the function that searches for the children(search key )
void create->The function that creates the children. I send a vector that contains only the children of that specific parent and not other children.
*typedef struct node
{
int value;
node *left;
node *right;
node *middle;
}TreeNodeParent;
int search_root(int in[9])
{
for (int i = 0; i < 9; i++)
{
if (in[i] == -1)
{
int var = i+1;
in[i] = -2;
return var;
}// pe else nu facem nimic
}
return -2;
}
int search_key(int in[9], int radacina)
{
for (int i = 0; i < 9; i++)
{
if (in[i] == radacina)
{
int var = i + 1;
in[i] = -2;
return var;
}
}
return -3;
}
TreeNodeParent *createOneNode(int value)
{
//the error appears here
TreeNodeParent* create = (TreeNodeParent*)malloc(sizeof(TreeNodeParent));
create->value = value;
create->left = create->middle = create->right = NULL;
return create;
}
void create(int vector[], TreeNodeParent* radacina)
{
for (int i = 0; i < 9; i++)
{
if (vector[i] == -3)//am stabilit ca -3 ii oprirea
{
break;
}
else
{
TreeNodeParent* create = createOneNode(vector[i]);
if (radacina->left == NULL)
{
radacina->left = create;
}
else if (radacina->middle == NULL)
{
radacina->middle = create;
}
else
{
radacina->right = create;
}
}
}
}
int main()
{
int input[9] = { 2,7,5,2,7,7,-1,5,2 };
int root = search_root(input);
if (root == -2)
{
printf("Nu gasim radacina, arbore incorect!");
}
else { printf("root %d", root); }
//crearea nodului parinte
TreeNodeParent* rootParent = (TreeNodeParent*)malloc(sizeof(TreeNodeParent*));
rootParent->value = root;
rootParent->left = NULL;
rootParent->right = NULL;
rootParent->middle = NULL;
int vect2[9];
for (int i = 0; i < 9; i++)//worst case, tot arborele is copii ai lui root->o(n2)
{
vect2[i] = search_key(input, root);
printf("copii rootului %d", vect2[i]);
if ( vect2[i] == -3)
{
break;
}
}
create(vect2,rootParent);
_getch();
return 0;
}
checked online with gdb :
> tin_offsetof (struct malloc_chunk, fd_nextsize))+((2 *(sizeof(size_t))) - 1)) & ~((2 *(sizeof(size_t))) - 1))) && ((ol
> d_top)->size & 0x1) && ((unsigned long) old_end & pagemask) == 0)' failed.
program exited
> with code 134
I can't understand why the function crashes only on the third(and not before). Also it does not always appear. Sometimes it works fine, other times it stops with that error.
Also If there is a better way to create a tree with a parent representation?
I think the problem is in your main() method, where you malloc() with sizeof(TreeNodeParent*) instead of sizeof(TreeNodeParent) and assign it to rootParent:
//crearea nodului parinte
//TreeNodeParent* rootParent = (TreeNodeParent*)malloc(sizeof(TreeNodeParent*));
TreeNodeParent* rootParent = (TreeNodeParent*)malloc(sizeof(TreeNodeParent)); `

Resources