I'm trying to make an implementation of merge() given 2 sorted linked lists, and output a linked list that merges the two and is sorted. I first create an array and put the items there, but when I print the array elements I get garbage values/seg fault. I know it's a lot of code to go through but I'd really appreciate anyone who can help :)
typedef struct _node {
int data;
struct _node * next;
} node_t;
typedef struct {
node_t * head;
node_t * tail;
} LL_t;
LL_t* createList(int num_nodes);
void printList(LL_t* L);
void merge(LL_t * L, LL_t * L2);
void merge(LL_t * L, LL_t * L2){
if(L2->head==NULL){ // empty L2
free(L2);
return;
}
else if(L->head==NULL){ // empty L1
*L=*L2;
free(L2);
return;
}
node_t* node=L->head;
int mid=0;
if(node->next!=NULL){
for (mid=0; node->next!=NULL; mid++) //finds last index of L1
node=node->next;
}
L->tail->next=L2->head;
L->tail=L2->tail;
node_t* ind = L->head;
free(L2);
int len=0;
for (len=0; ind!=NULL; len++) // finds num of items in list
ind=ind->next;
int arr[len];
int newarr[len];
node_t* cur= L->head;
for(int i=0; cur!=NULL; i++){ // creates array with list items
arr[i]=cur->data;
cur=cur->next;
}
int first=0;
int last=len;
int leftpos=0;
int rightpos=mid+1;
int newpos=0;
// insert elements to arr until a half of the array
// reaches mid or last
while(leftpos<=mid && rightpos<=last-1){
if(arr[leftpos]<arr[rightpos]){
newarr[newpos++]=arr[leftpos++];
}
else
newarr[newpos++]=arr[rightpos++];
}
// fills in the rest of the array
while(leftpos<=mid)
newarr[newpos++]=arr[leftpos++];
while(rightpos<=last)
newarr[newpos++]=arr[leftpos++];
for(int j=0; j<len; j++)
printf("newarr=%d\n",newarr[j]);
}
int main(void){
int num_nodes = 4;
int num_nodes2 = 3;
LL_t* L=createList(num_nodes);
LL_t* L2=createList(num_nodes2);
merge(L, L2);
}
// Creates the list. No problem here
LL_t* createList(int num_nodes){
LL_t* L = malloc(sizeof(LL_t));
L->head=NULL;
L->tail=NULL;
node_t *n;
int i=0;
for (i = 0; i < num_nodes; i++) {
n = malloc(sizeof(*n));
scanf("%d",&n->data);
n->next = NULL;
if (L->head == NULL){
L->head = n;
L->tail = n;
}
else {
L->tail->next = n;
L->tail = n;
}
}
puts("\n");
return L;
}
The problem is here in the merge():
while(rightpos<=last)
newarr[newpos++]=arr[leftpos++];
^^^^^^^
Here, the condition of while loop is rightpos<=last but accessing leftpos index element of arr and incrementing it. And if rightpos is less than last then the while loop condition will always be true which makes it an infinite loop. Every iteration of while loop is incrementing leftpos, at one stage its value will be greater than the size of array arr and accessing the array element beyond the size of the array is undefined behavior which includes program may give segmentation fault. It should be:
while(rightpos<=last)
newarr[newpos++]=arr[rightpos++];
Related
My program inputs a sequence of elements and checks if a up to down sequence of the same numbers exists in a binary tree.
To be clear, I am submitting my answer to a system set up by my professor that just responds with a Failed - run time error, with no other details. When I compile and run it on Xcode, it works perfectly fine with no run time errors. I have checked for divide by zero, memory leakage, array out of bounds etc but I can't seem to spot the error. For this reason my code will be a bit lengthy because I can't figure out the problematic part.
node *n;
node *newNode(int data)
{
node *new_node = (node *)malloc(sizeof(node));
new_node->number = data;
new_node->left = NULL;
new_node->right = NULL;
return new_node;
}
node *insert(int arr2[], node *ptr, int i, int M2, int x)
{
if (i < M2)
{
node *temp = newNode(arr2[i]);
ptr = temp;
if (ptr -> number == x)
n = ptr; // n is a global variable of type node*
ptr->left = insert(arr2, ptr->left, 2 * i + 1, M2, x);
ptr->right = insert(arr2, ptr->right, 2 * i + 2, M2, x);
}
return ptr;
}
void checkPath(int arr1[], node *ptr, int *i, int M1)
{
node *temp = (node *)malloc(sizeof(node));
if (n == NULL)
return;
while ((*i) < M1)
{
if (n->left->number == arr1[*i])
{
(*i)++;
temp = n->left;
n = temp;
}
else if(n->right->number == arr1[*i])
{
(*i)++;
temp = n -> right;
n = temp;
}
else
break;
}
}
int main()
{
int N, M1, M2, z;
scanf("%d", &N);
for (int i = 0; i < N; i++)
{
z = 1;
scanf("%d", &M1);
int arr1[M1];
for (int j = 0; j < M1; j++)
scanf("%d", &arr1[j]);
scanf("%d", &M2);
int arr2[M2];
for (int k = 0; k < M2; k++)
scanf("%d", &arr2[k]);
node *ptr = (node *)malloc(sizeof(node));
ptr = insert(arr2, ptr, 0, M2, arr1[0]);
checkPath(arr1, ptr, &z, M1);
if (z == M1)
printf("True\n");
else
printf("False\n");
free(ptr);
}
return 0;
}
Sorry for the lengthy piece of code. Thanks in advance!
At least this problem: lost memory.
checkPath() never uses the result of malloc(). This suggest a logical error in this function.
void checkPath(int arr1[], node *ptr, int *i, int M1)
{
node *temp = (node*) malloc(sizeof(node));
...
while((*i) < M1)
...
temp = n -> left;
n = temp;
...
temp = n -> right;
n = temp;
...
}
}
It is concerning code is reading and setting a global variable n here.
This may or may not be a key problem.
What about input data? Is it guaranteed to be OK or not?
There is no validation at data input in the code.
Well, I've just reproduced the failure:
./test
2
1
1
1
1
True
2
2
2
2
2
2
Segmentation fault (core dumped)
Given that 'node' is this:
typedef struct _node
{
int number;
struct _node *left;
struct _node *right;
} node;
But the actual error in logic I didn't find yet.
BTW the logic is somewhat curious.
P.S. this input would also give a crash:
./test
2
2
2
2
2
2
2
2
Segmentation fault (core dumped)
Consider adding pointer checks before accessing 'left' or 'right'
if (n->left && n->left->number == arr1[*i])
and
else if(n->right && n->right->number == arr1[*i])
I was asked to build a function that's receive a static two dimensional array with a lot of zeroes and turn it to an array of structs. each struct contains the value which is not zero and the index of the column.
Now I have built it but the problem is with the print function.
1) When I try to print twice it only prints one time and the second time list becomes NULL. Why does this occur?
print(list);
print(list);
2) Why can't I print like I did in the main function?
printf("this is just a print |%d||%d| ", list[0]->next->next->next->data, list[0]->col);
Why I don't have access to it, the program crashes...
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
//#include <vld.h>
#include <string.h>
#include <ctype.h>
#define C 5
#define N 4
typedef struct Node {
int data;
int col;
struct Node *next;
} node;
node **fun(int arr[N][C]) {
int i, j, k;
node **list;
node *temp;
list = (node**)calloc(N, sizeof(node *));
for (i = 0; i < N; i++) {
list[i] = NULL;
for (j = C - 1; j >= 0; j--)
if (arr[i][j] != 0) {
temp = (node*)malloc(sizeof(node));
temp->data = arr[i][j];
temp->col = j;
temp->next = list[i];
list[i] = temp;
}
}
return list;
}
void print(node **head) {
int i;
node **temp = head;
for (i = 0; i < N; i++) {
while (temp[i]) {
printf("|%d||%d| ", temp[i]->data, temp[i]->col);
temp[i] = temp[i]->next;
}
printf("\n\n");
}
}
void main() {
int arr[N][C] = { {0,0,4,0,7}, {3,0,0,0,0}, {9,1,0,6,0} , {0,0,0,0,0} };
node **list;
list = fun(arr);
print(list); ///////////
print(list); ///////////////
printf("this is just a print |%d||%d| ", list[0]->next->next->next->data, list[0]->col);
}
As was mentioned in the comments, you are destroying your list of pointer in the process of printing them:
while(temp[i])
{ printf("|%d||%d| ",temp[i]->data,temp[i]->col);
temp[i]=temp[i]->next; // <---- here
}
Each temp[i] is the same as head[i], so you modify the original list as you do this. The while loop exits when this value is NULL, so the end result is that all array elements are NULL.
You need to assign this value to a temporary so you can walk the list without changing it:
node *temp2 = temp[i];
while(temp2)
{ printf("|%d||%d| ",temp2->data,temp2->col);
temp2=temp2->next;
}
Your print function modifies the array: it uses the array elements to iterate through the lists, and leaves them with a NULL value.
Here is a corrected version:
void print(node **head) {
int i;
for (i = 0; i < N; i++) {
node *temp;
for (temp = head[i]; temp; temp = temp->next) {
printf("|%d||%d| ", temp->data, temp->col);
}
printf("\n\n");
}
}
I try to write a function which is used to build a BST from an array of integers. It takes 2 arguments: pointer to the array and the size of the array
create the BST with successive inserts and return the pointer to the tree
if size is 0, return NULL
sample;
int a[3] = {2,1,3};
return build(a, 3);
My work is here, but there is a problem in the recursion part, I cannot find my mistake, actually I know that I cannot use for loops correctly, but cannot solve.
In my code, firstly I changed format of array in an ascending order, then took the middle number, and made it root, then for left and right parts, I should do same things.
By the way, I have an insert function implementation, but I am not sure, can we need or use it in build function.
typedef struct TreeNode{
int val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
TreeNode* build(int *array, int size) {
TreeNode *root = malloc(sizeof(TreeNode));
int a,i,j;
int mid = size/2;
if(size==0)
return NULL;
else {
for(i=0;i<size;i++) {
for(j=i+1;j<size;j++) {
if(array[i] > array[j]) {
a = array[i];
array[i] = array[j];
array[j] = a;
}
}
}
root->val = array[mid];
for(i=0;i<mid;i++)
root->left = build(array, mid);
for(i=(mid+1);i<size;i++)
root->right = build(array, mid);
return root;
}
}
Modify according to your concept:
#include <stdio.h>
#include <stdlib.h>
typedef struct TreeNode{
int val;
struct TreeNode *left;
struct TreeNode *right;
} TreeNode;
TreeNode* build(int *array, int size) {
if(size == 0)
return NULL;
else {
TreeNode *root = malloc(sizeof(TreeNode));//in the case of return NULL there is before if-block, cause of memory leak
int i, j, mid;
int swap = 1;
j = size-1;
while(swap){//To deter a repeat of the sort
swap = 0;
for(i = 0; i < j; ++i) {
if(array[i] > array[i+1]) {
int temp = array[i];
array[i] = array[i+1];
array[i+1] = temp;
swap = 1;
}
}
--j;
}
root->val = array[mid = size / 2];
root->left = build(array, mid);
root->right = build(array + mid + 1, size - mid -1);
return root;
}
}
void print(TreeNode *p){
if(p){
print(p->left);
printf("%d ", p->val);
print(p->right);
}
}
int main(void){
//test
int a[] = {1,5,9,2,6,4,8,3,7,0};
TreeNode *root = build(a, 10);
print(root);
//deallocate
return 0;
}
I am trying to sort a linked list using bubble sort.But it gives segmentation problem
My logic to do so is below:
Note: Please note that i have to use only pass by reference every where (no return and global declaration for nodes)
void bubble_sort(node * * List, int size)
{
int i, j, temp;
node * first;
node * second;
node * final;
final=*List
for (i = 0; i < size - 1; i++)
{
first =final;
second = first -> link;
for (j = 0; j < size; j++)
{
if (first -> data < second -> data)
{
temp = first -> data;
first -> data = second -> data;
second -> data = temp;
}
first = first -> link;
}
} * List = first;
}
It's function call is :
bubble_sort(&start,val);
Could any one please help me in correcting the logic ?
EDIT: My full code:
#include <stdio.h>
//#include <conio.h>
#include <malloc.h>
/* structure containing a data part and link part */
struct node
{
int data;
struct node * link;
};
typedef struct node node;
node * start, * visit, * newnode;
//start=NULL
///////////////////////////////// Function declaration ///////////////////
void append(node * * q, int num);
void displaylist(node * start);
void bubble_sort(node * * List, int val);
//////////////////////////////////////////////////////////////////////////////////////////
void append(node * * q, int num)
{
node * temp, * temp2;
temp = * q;
//temp= (node* )malloc(sizeof (node));
if (temp == NULL) /* if the list is empty, create first node */
{
temp = (node * ) malloc(sizeof(struct node)); * q = temp;
} else
{
temp2 = * q;
while (temp2 -> link != NULL)
{
temp2 = temp2 -> link;
}
temp = (node * ) malloc(sizeof(struct node));
temp2 -> link = temp;
}
temp -> data = num;
temp -> link = NULL;
}
///////////////////////////////////////////////////////////////////////
void displaylist(node * start)
{
visit = start;
/* traverse the entire linked list */
while (visit != NULL)
{
printf("%d ", visit -> data);
visit = visit -> link;
}
}
/////////////////////////////////////////////////////////////////////////////////
/*
void bubble_sort(node **List,int size)
{
int i,j,temp;
node*first;
node*second;
node*final;
final=*List;
for(i=0;i<size-1;i++)
{
first=final;
second=first->link;
for(j=1;j<size;j++)
{
if( first->data<second->data)
{
temp=first->data;
first->data=second->data;
second->data=temp;
}
first=first->link;
}
}
*List=first;
} */
//////////////////////////////////////////////////////////////////////////////////////
void bubble_sort(node * * List, int size)
{
int i, j, temp;
node * first;
node * second;
node * final;
for (i = 0; i < size; i++)
{
first = * List;
for (j = 0; j < size - 1; j++)
{
if (first -> data < first -> link -> data)
{
temp = first -> data;
first -> data = first -> link -> data;
first -> link -> data = temp;
}
first = first -> link;
}
}
}
////////////////////////////////////////////////////////////////////////////////////////////
main()
{
start = NULL;
int val, n, size;
char ch;
struct node * new;
new = NULL;
printf("\nEnter the size desired size of Linked list: \n");
scanf("%d", & size);
for (ch = 0; ch < size; ch++)
{
printf("\nEnter a value: ");
scanf("%d", & val);
append( & new, val);
}
start = new;
displaylist(start);
printf("\nApplying Bubble sort on Linked list: \n");
bubble_sort( & start, val);
displaylist(start);
printf("\n");
}
Assumed Val is number of nodes in list, you are actually not sorting a linked list but instead swapping the values from one node to another in order to sort it.
bubble_sort( &start, size); change this as well should fix it(pass size not val)
try this.
void bubble_sort(node **List, int val)
{
int i,j,temp;
node *first;
node *second;
node *final;
for(i = 0; i < val; i++)
{
first = *list
for(j = 0; j < val-1; j++)
{
if(first->data < first->link->data)
{
temp = first->data;
first->data = first->link->data;
first->link->data = temp;
}
first = first->link;
}
}
}
I believe you are getting a segmentation fault because you're trying to access a Null pointer as a node, in the inner for-loop.
for (j = 0; j < val; j++)
this should be:
for (j = 0; j < val - 1; j++)
Because in your solution, when j = val-1, it will still try and access first->link->data, however, first->link is Null.
I am trying to do an efficient sparse matrix multiplication. Right now I am reading the data into memory and this is how my data structure looks like:
typedef struct node{
int x;
int y;
int value;
struct node* row;
struct node* col;
}node;
typedef struct matrix{
int height;
int width;
node** rowList;
node** colList;
}matrix;
My current code for the insertion is:
void insert(matrix** M, int row_index, int col_index, int value)
{
node* currNode=(node*)malloc(sizeof(node));
currNode->x=row_index;
currNode->y=col_index;
currNode->value=value;
if ((*M)->rowList[row_index] == NULL) { /* index is empty */
currNode->row = NULL;
(*M)->rowList[row_index] = currNode;
}
else if ((*M)->rowList[row_index]->y > col_index) { /* insert node to front */
//printf("%d, %d\n", (*M)->rowList[row_index]->y, col_index);
currNode->col = (*M)->rowList[row_index];
(*M)->rowList[row_index] = currNode;
}
else if ((*M)->rowList[row_index]->y < col_index) { /* insert node to front */
node* rowptr = (node*)malloc(sizeof(node));
rowptr = (*M)->rowList[row_index];
while(rowptr->col!=NULL&&rowptr->col->y < col_index)
rowptr=rowptr->col;
currNode->col=rowptr->col;
rowptr->col=currNode;
//printf("-----------------%d\n", rowptr->y);
}
if ((*M)->colList[col_index] == NULL) {
currNode->col = NULL;
(*M)->colList[col_index] = currNode;
}
else
if ((*M)->colList[col_index]->x > row_index) {
//printf("%d, %d\n", (*M)->colList[col_index]->x, row_index);
currNode->row = (*M)->colList[col_index];
(*M)->colList[col_index] = currNode;
}
}
In case of you ask, this is my print function:
void print_matrix(matrix *M){
for(int i=0;i<M->height;i++){
while(M->rowList[i]!=NULL){
printf("i=%d, j=%d, v=%d\n",M->rowList[i]->x, M->rowList[i]->y,
M->rowList[i]->value);
M->rowList[i]=M->rowList[i]->col;
}
}
}
For this input:
5,5
0,0,1
0,1,2
0,3,3
0,4,4
where (5,5) matrix dimensions and (0,0,1) = i,j,value, I get this:
i=0, j=0, v=1
i=0, j=1, v=2
i=0, j=3, v=3
i=0, j=4, v=4
i=0, j=4, v=4
For this input:
5,5
0,0,1
0,1,2
0,3,3
0,4,4
0,2,5
I get this:
i=0, j=0, v=1
i=0, j=1, v=2
i=0, j=2, v=5
i=0, j=2, v=5
I think the problem is here:
else if ((*M)->rowList[row_index]->y < col_index) {
node* rowptr = (node*)malloc(sizeof(node));
rowptr = (*M)->rowList[row_index];
while(rowptr->col!=NULL&&rowptr->col->y < col_index)
rowptr=rowptr->col;
currNode->col=rowptr->col;
rowptr->col=currNode;
}
[ ... ]
Somehow I remove one of the values when I add a new element that is smaller.
The question is : how can I get this code to load my sparse matrix values into memory using the data structure provided correctly?
Thank you ^^
Here:
if ((*M)->colList[col_index] == NULL) {
currNode->col = NULL;
(*M)->colList[col_index] = currNode;
}
where you write currNode->col, you should have written currNode->row. After making this change the output is correct for the second input file.
While looking at the code I noticed other odd things; for example, the print_matrix function also destroys the matrix ->col pointer chains. Also, in these two lines
node* rowptr = (node*)malloc(sizeof(node));
rowptr = (*M)->rowList[row_index];
you're allocating memory and then immediately overwriting the pointer to it.