I have a simple function that should perform enqueuing based on the following algorithm:
Algorithm: ENQUEUE (Q, ITEM)
[Q is an array represent queue and ITEM is deleted item]
1. [check overflow]
If Rear = MAX - 1 then
a) Print: Queue is Full
b) Return
2. Set Rear = Rear + 1
3. Q[Rear] = ITEM
4. Return
I have attempted two approaches and one provides me with a segmentation fault error, and I cannot understand why.
Here is the working implementation:
#define MAXSIZE 255
typedef struct Stack {
int Q[MAXSIZE];
int rear;
} Stack_t;
int enqueue(int item,int(*Q)[item] ){
int rear;
if (rear == sizeof(*Q)/sizeof((*Q)[0])-1){
printf("Queue is Full!");
return -1;
}
rear++;
(*Q)[rear] = item;
return rear;
}
int main(void){
Stack_t s = {.rear = -1};
int arr[10] = {0, 1, 2, 3, 4, 5};
int item = 2;
int result;
result = enqueue(item, &arr);
printf("\nResult: {%i}", arr[result]);
return 0;
}
This will print out:
Queue is Full!
Result: {0}%
Whereas, the original implementation I had in mind would not work, it goes likeso:
int enqueue(int(*Q)[], int item, int size){
int rear;
if (rear == size-1){
printf("Queue is Full!");
return -1;
}
rear++;
(*Q)[rear] = item;
return rear;
}
int main(void){
Stack_t s = {.rear = -1};
Stack_t q = {.Q = {0, 1, 2, 3, 4, 5}};
int arr[10] = {0, 1, 2, 3, 4, 5};
int item = 2;
int result;
int size = sizeof(q.Q)/sizeof(q.Q[0]);
result = enqueue(&q.Q, item, size);
printf("\nResult: {%i}", q.Q[result]);
return 0;
}
I am new to indexing structs and recently learnt them from my latest question (before this one.) So perhaps q.Q is not the exact expression, otherwise, the size is not properly captured.
Use the array in the struct to store the enqueued integers.
Pass a pointer to the structure to the function.
#include <stdio.h>
#define MAXSIZE 255
typedef struct Stack {
int Q[MAXSIZE];
int rear;
} Stack_t;
int enqueue ( int item, Stack_t *q){
int max = ( sizeof q->Q / sizeof q->Q[0]) - 1;
if ( q->rear == max) {
printf ( "Queue is Full!\n");
return q->rear;
}
q->rear++;
q->Q[q->rear] = item;
return q->rear;
}
int main ( void) {
Stack_t s = {.rear = -1};
int item = 2;
int result;
result = enqueue ( item, &s);
printf ( "Result: {%i}\n", s.Q[result]);
item = 12;
result = enqueue ( item, &s);
printf ( "Result: {%i}\n", s.Q[result]);
return 0;
}
Related
I am trying to write codes in C for dynamic array (vector), and it runs okay until I add another function pointer into the struct (line29: int (findEle)(vector, int) ), and initialize it (line 153: v->findEle = findEle) to point to the function implementation (line 125: int findEle(vector* v, int value)). The debugger starts returning segmentation fault every time I tried to run it. Please find the code below:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
typedef int BOOL;
#define TRUE 1
#define FALSE 0
typedef struct Vector vector;
struct Vector
{
int currCapacity;
int currSize;
int *items;
// TODO: Try to add another int field, will cause seg fault
int (*size)(vector*);
int (*capacity)(vector*);
BOOL (*is_empty)(vector*);
void *(*at)(vector*, int);
void (*push)(vector*, int);
void (*insert)(vector*, int, int);
void (*resize)(vector*, size_t);
int (*pop)(vector*);
void (*removeValue)(vector*, int);
void (*delete_ele)(vector*, int);
int (*findEle)(vector*, int);
};
// Vector Functions
int size(vector *v)
{
return v->currSize;
}
int capacity(vector *v)
{
return v->currCapacity;
}
BOOL is_empty(vector *v)
{
if(v->currSize==0){ return TRUE; }
return FALSE;
}
void *at(vector *v, int index)
{
if(index >= v->currSize){return NULL;}
return (int*)(v->items+index);
}
void push(vector *v, int item)
{
if(v->currSize == v->currCapacity)
{
v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
v->currCapacity = v->currCapacity * 2;
}
*(v->items+v->currSize) = item;
v->currSize++;
}
void insert(vector* v, int index, int item)
{
printf("Inserting %d at index %d\n", item, index);
if(v->currSize == v->currCapacity)
{
v->items = (int*)realloc(v->items, sizeof(int)* (v->currCapacity * 2));
printf("v->items address: %p\n", v->items);
v->currCapacity = v->currCapacity * 2;
}
int* shift_ptr = v->items+index;
memmove(v->items+index+1, v->items+index, sizeof(int)*(v->currSize-index));
*(v->items+index) = item;
v->currSize++;
}
void resize(vector* v, size_t size)
{
printf("Resizing from %d to %d\n", v->currSize, size);
v->items = (int*)realloc(v->items, sizeof(int)* size);
}
int pop(vector* v)
{
int last = *(v->items + (v->currSize-1));
v->currSize--;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
return last;
}
void delete_ele(vector* v, int index)
{
int *curr_ptr = v->items+index;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
memmove(curr_ptr, curr_ptr+1, sizeof(int)*(v->currSize-(index+1)));
v->currSize--;
}
void removeValue(vector *v, int value)
{
for(int i=0; i<v->currSize; i++)
{
int ptr_value = *(v->items+i);
printf("%d->%d ", i, ptr_value);
if(ptr_value==value)
{
delete_ele(v, i);
--i;
}
}
printf("\n");
}
int findEle(vector* v, int value)
{
for(int i=0; i<v->currSize; i++)
{
if(*(v->items+i)==value)
{
return i;
}
}
return -1;
}
vector *initializeVector()
{
vector *v;
v->currSize = 0;
v->currCapacity = 2;
v->items = (int*)malloc(sizeof(int) * v->currCapacity);
v->size = size;
v->capacity = capacity;
v->is_empty = is_empty;
v->at = at;
v->push = push;
v->insert = insert;
v->pop = pop;
v->removeValue = removeValue;
v->delete_ele = delete_ele;
v->findEle = findEle;
return v;
}
int main()
{
vector *v = initializeVector();
v->push(v, 8);
v->push(v, 25);
v->push(v, 25);
v->push(v, 12);
printf("element 0 :%d\n", *(int*)v->at(v, 0));
printf("element 1 :%d\n", *(int*)v->at(v, 1));
printf("element 2 :%d\n", *(int*)v->at(v, 2));
printf("element 3 :%d\n", *(int*)v->at(v, 3));
v->insert(v, 1, 50);
printf("element 0 :%d\n", *(int*)v->at(v, 0));
printf("element 1 :%d\n", *(int*)v->at(v, 1));
printf("element 2 :%d\n", *(int*)v->at(v, 2));
printf("element 3 :%d\n", *(int*)v->at(v, 3));
printf("element 4 :%d\n", *(int*)v->at(v, 4));
//printf("%d\n", v->pop(v));
printf("%d\n", v->findEle(v, 25));
v->removeValue(v, 25);
for(int i=0; i<v->currSize; i++)
{
int ptr_value = *(v->items+i);
printf("%d->%d ", i, ptr_value);
}
free(v->items);
return 0;
}
I tried to debug using gdb, it returns the below message:
Program received signal SIGSEGV, Segmentation fault.
0x0040189a in initializeVector () at Vector.c:153
153 v->findEle = findEle;
When I tried to get the address of the stated function, it showed the message below:
(gdb) x v->findEle
Cannot access memory at address 0x620000
Can someone kindly advice if I have some issues on memory allocation? Or the issue might be due to some other causes? Thanks!
At least in these functions
void resize(vector* v, size_t size)
{
printf("Resizing from %d to %d\n", v->currSize, size);
v->items = (int*)realloc(v->items, sizeof(int)* size);
}
int pop(vector* v)
{
int last = *(v->items + (v->currSize-1));
v->currSize--;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
return last;
}
void delete_ele(vector* v, int index)
{
int *curr_ptr = v->items+index;
if(v->currSize*4 == v->currCapacity)
{
v->resize(v, v->currCapacity/2);
}
memmove(curr_ptr, curr_ptr+1, sizeof(int)*(v->currSize-(index+1)));
v->currSize--;
}
you do not update data members currCapacity and currSize
And in this function
vector *initializeVector()
{
vector *v;
v->currSize = 0;
v->currCapacity = 2;
v->items = (int*)malloc(sizeof(int) * v->currCapacity);
v->size = size;
v->capacity = capacity;
v->is_empty = is_empty;
v->at = at;
v->push = push;
v->insert = insert;
v->pop = pop;
v->removeValue = removeValue;
v->delete_ele = delete_ele;
v->findEle = findEle;
return v;
}
there is used the uninitialized pointer v that has an indeterminate value that results in undefined behavior.
Also you need to check the value of the parameter index in each function where it is used.
What I am trying to do is to create a counting sort using a linked list so I can link two similar elements in the same index and then copy from left to right to the original array. But my Buckets[i] are always NULL even after insertion. So my resulting array does not change. I don't know what I am doing wrong.
#include <stdio.h>
#include <stdlib.h>
struct Node {
int data;
struct Node *next;
} **Buckets;
void printArray(int arr[], int size) {
for (int i = 0; i < size; i++)
printf("%d ", arr[i]);
printf("\n");
}
int findMax(int A[], int n) {
int i, max = A[0];
for (i = 0; i < n; i++) {
if (A[i] > max)
max = A[i];
}
return max;
}
void Insert(struct Node *p, int x) {
while (p != NULL) {
p = p->next;
}
Node *t = t = (struct Node *)malloc(sizeof(struct Node));
t->data = x;
t->next = NULL;
p = t;
}
int Delete(struct Node *Buckets) {
while (Buckets->next != NULL) {
Buckets = Buckets->next;
}
int temp = Buckets->data;
free(Buckets);
return temp;
}
void BucketSort(int A[], int size) {
int max, i, j;
max = findMax(A, size);
Buckets = new Node * [max + 1];
for (i = 0; i < max + 1; i++) {
Buckets[i] = NULL;
}
for (i = 0; i < size; i++) {
Insert(Buckets[A[i]], A[i]); //insertion
}
i = j = 0;
while (i < max + 1) {
while (Buckets[i] != NULL) {
A[j++] = Delete(Buckets[i]); // copy back in array
}
i++;
}
}
int main() {
int arr[] = { 3, 8, 5, 1, 10 };
int size = sizeof(arr) / sizeof(arr[0]); //5
printf("\nBefore : ");
printArray(arr, size);
BucketSort(arr, size);
printf("\nAfter : ");
printArray(arr, size);
return 0;
}
Your Insert function doesn't really modify the list – you just assign the new node to a local variable, which goes out of scope immediately.
You can solve this by passing a pointer to a node pointer to the function. That pointer points at the head pointer at first and at the next member of the preceding node when you advance:
void Insert(struct Node **p, int x)
{
while (*p) p = &(*p)->next;
*p = new Node(x); // assume a c'tor here
}
Call the function like so:
for (i = 0; i < size; i++) {
Insert(&Buckets[A[i]] ,A[i]);
}
The same goes for deletion: You must modify the links or the list head when you delete:
int Delete(struct Node **p)
{
int temp = (*p)->data;
struct Node *del = *p;
*p = (*p)->next;
delete del;
return temp;
}
(This code extracts the head node, which is probably what you want: You insert at the end, then retrieve from the beginning. That should preserve the original order. Not that it matters miuch in your case, where you have no data beside the int.)
Call Delete like so:
i = j = 0;
while (i < max + 1) {
while (Buckets[i]) {
A[j++] = Delete(&Buckets[i]);
}
i++;
}
I need to put inside an array, the values of a binary tree, but the thing is, I should only put inside the array the values that are at a certain depth. And it should output the number of elements inserted at the array.
I have made this:
int nivel2_(ABin a, int n, int v[], int level, int *i){
int t;
if(!a) return 0;
if(n == level){
v[(*i)++] = a->value;
return 1;
}else{
t = nivel2_(a->left, n, v, level+1, i) + nivel2_(a->right, n, v, level+1, i);
}
return t;
}
int nivel2(ABin a, int n, int v[]){
int k = 0;
int *i;
i = &k;
return nivel2_(a, n, v, 1, i);
}
As I will keep changing the index recursively and only when we reach the depth we want, I thought of using a pointer, this way, when one part of the recursive folding happens it will change the value to all the other folding processes. Makes sense?
Structures:
typedef struct slist
{
int value;
struct slist* next;
} *SList;
typedef struct arvbin* ABin;
typedef struct arvbin
{
int value;
ABin right;
ABin left;
} arvb;
DOES IT WORK?
Only when I want the elements of the first level of depth!
Calling like this:
nivel2(tree2, 1, v);
Complete code
#include <stdio.h>
#include <stdlib.h>
typedef struct slist
{
int value;
struct slist* next;
} *SList;
typedef struct arvbin* ABin;
typedef struct arvbin
{
int value;
ABin right;
ABin left;
} arvb;
int nivel2_(ABin a, int n, int v[], int level, int *i){
int t;
if(!a) return 0;
if(n == level){
v[(*i)++] = a->value;
return 1;
}else{
t = nivel2_(a->left, n, v, level+1, i) + nivel2_(a->right, n, v, level+1, i);
}
return t;
}
int nivel2(ABin a, int n, int v[]){
int k = 0;
int *i;
i = &k;
return nivel2_(a, n, v, 1, i);
}
void insertTree(ABin *tree, int val){
if((*tree)==NULL){
*tree = (ABin) malloc(sizeof(arvb));
(*tree)->value = val;
(*tree)->left = NULL;
(*tree)->right = NULL;
return;
}
else if(val > (*tree)->value)
{
insertTree(&((*tree)->right), val);
}
else if(val <= (*tree)->value)
{
insertTree(&((*tree)->left), val);
}
return;
}
int main(){
int v[10] = {0};
ABin tree2 = NULL;
insertTree(&tree2, 22);
insertTree(&tree2, 1);
insertTree(&tree2, 3);
nivel2(tree2, 1, v);
int i;
for(i=0; i<5; i++){
printf("%d\n", v[i]);
}
return 0;
}
The code looks mostly OK to me. Here's a mildly modified version, mainly with a tree printing function added, and some diagnostics, and an extended tree. My suspicion is that you expected your tree to have just 2 levels, but it actually had 3.
Code
#include <stdio.h>
#include <stdlib.h>
typedef struct slist
{
int value;
struct slist* next;
} *SList;
typedef struct arvbin* ABin;
typedef struct arvbin
{
int value;
ABin right;
ABin left;
} arvb;
static int nivel2_(ABin a, int n, int v[], int level, int *i)
{
int t = 0;
if (a)
{
if (n == level)
{
v[(*i)++] = a->value;
t = 1;
}
else
{
t += nivel2_(a->left, n, v, level + 1, i);
t += nivel2_(a->right, n, v, level + 1, i);
}
}
return t;
}
static int nivel2(ABin a, int n, int v[])
{
int k = 0;
int r = nivel2_(a, n, v, 1, &k);
printf("r = %d; k = %d\n", r, k);
return k;
}
static
void insertTree(ABin *tree, int val)
{
if ((*tree) == NULL)
{
*tree = (ABin) malloc(sizeof(arvb));
(*tree)->value = val;
(*tree)->left = NULL;
(*tree)->right = NULL;
return;
}
else if (val > (*tree)->value)
{
insertTree(&((*tree)->right), val);
}
else if (val <= (*tree)->value)
{
insertTree(&((*tree)->left), val);
}
}
static void tree_to_array(ABin tree, int level)
{
int v[10] = { 0 };
int n = nivel2(tree, level, v);
printf("Converted level %d to array:", level);
for (int i = 0; i < n; i++)
printf(" %d", v[i]);
putchar('\n');
}
static void print_tree(ABin tree, int level)
{
if (tree != 0)
{
printf("Level %d: %d\n", level, tree->value);
print_tree(tree->left, level + 1);
print_tree(tree->right, level + 1);
}
}
int main(void)
{
ABin tree2 = NULL;
insertTree(&tree2, 22);
insertTree(&tree2, 10);
insertTree(&tree2, 13);
insertTree(&tree2, 33);
insertTree(&tree2, 39);
insertTree(&tree2, 43);
insertTree(&tree2, 19);
print_tree(tree2, 1);
for (int level = 1; level < 5; level++)
tree_to_array(tree2, level);
return 0;
}
Sample output
Level 1: 22
Level 2: 10
Level 3: 13
Level 4: 19
Level 2: 33
Level 3: 39
Level 4: 43
r = 1; k = 1
Converted level 1 to array: 22
r = 2; k = 2
Converted level 2 to array: 10 33
r = 2; k = 2
Converted level 3 to array: 13 39
r = 2; k = 2
Converted level 4 to array: 19 43
That looks correct to me for the tree shape that's printed.
Assume the inputs are
a = [2,3,4,1]
b = [1,2,4,3]
The function DoThis takes the first input and gives the following output.
3,2,4,1,
2,4,3,1,
2,3,1,4,
1,3,4,2
The DoThis function is as follows:
int **DoThis(int n, int arr[n]){
int l = n;
int **b = malloc(l * sizeof(*b));//sizeof(*b) : sizeof(int *)
int i, j, k;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
int *copy = malloc(l * sizeof(*copy));//sizeof(int)
for (k = 0; k < l; k++)
copy[k] = arr[k];
int t = copy[i];
copy[i] = copy[j];
copy[j] = t;
//printf("{%d, %d, %d, %d}\n", copy[0], copy[1], copy[2], copy[3]);
b[i] = copy;
}
return b;
}
This function will be then performed on all the output produced at first level and so on, until the input . So it will look like this.
Since we found [1,2,4,3], we stop the function and output as 2, as it is in level 2.
How can I do this??
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stdbool.h>
typedef struct element {
int *array;
int size;
} Element;
bool Element_equal(Element *a, Element *b){
return a->size == b->size && memcmp(a->array, b->array, a->size * sizeof(*a->array))==0;
}
Element *E_copy(Element *e){
Element *el = malloc(sizeof(*el));
el->array = malloc(e->size * sizeof(*e->array));
memcpy(el->array, e->array, e->size * sizeof(*e->array));
el->size = e->size;
}
void E_print(Element *e){
int i;
for(i=0; i<e->size; i++)
printf("%d ", e->array[i]);
printf("\n");
}
void E_drop(Element *e){
free(e->array);
free(e);
}
typedef struct node {
Element *data;
int level;
struct node *next;
} Node;
void Node_drop(Node *node){
E_drop(node->data);
free(node);
}
typedef struct queque {
Node *top;
Node *tail;
} Queque;
Queque *Q_new(void){
return calloc(1, sizeof(Queque));
}
Node *Q_deq(Queque *q){
if(q->top){
Node *node = q->top;
q->top = q->top->next;
return node;
}
return NULL;
}
void Q_drop(Queque *q){
Node *node;
while(node = Q_deq(q))
Node_drop(node);
free(q);
}
void Q_enq(Queque *q, Element *element, int level){
Node *node = malloc(sizeof(*node));
node->data = element;
node->level = level;
node->next = NULL;
q->tail = q->top ? (q->tail->next = node) : (q->top = node);
}
Element **transpose(Element *e){
int l = e->size;
Element **b = malloc(l * sizeof(*b));
int i, j;
for (i = 0; i < l; i++) {
j = (i + 1) % l;
Element *copy = E_copy(e);
int t = copy->array[i];
copy->array[i] = copy->array[j];
copy->array[j] = t;
b[i] = copy;
}
return b;
}
int Cyc_Ken_Tau(Element *start, Element *goal){
Queque *queque = Q_new();
Q_enq(queque, E_copy(start), 0);//level 0
while(true){
Node *node = Q_deq(queque);
if(Element_equal(node->data, goal)){
int ret = node->level;
Node_drop(node);
Q_drop(queque);
return ret;
}
Element **new_list = transpose(node->data);
int i;
for(i=0; i < node->data->size; ++i){
Q_enq(queque, new_list[i], node->level + 1);
}
free(new_list);
Node_drop(node);
}
}
int main(){
int a[] = {2, 3, 4, 1};
int b[] = {1, 2, 4, 3};
int n = sizeof(a)/sizeof(*a);
Element start = { a, n };
Element goal = { b, n };
int level = Cyc_Ken_Tau(&start, &goal);
printf("%d\n", level);
return 0;
}
Use memcmp to compare your permutation to the desired one.
Also, be sure to match some frees to your mallocs when you're done with the data to avoid memory leaks.
I am trying to implement a vector or arraylist in C. The code does not have a main, so I am compiling it with gcc -c file.c . I have two questions, the first being how to implement an insert function for the arraylist, and the second being why I receive the error that list-> is not a function.
#include<stdio.h>
#include<stdlib.h>
#include<math.h>
#include<string.h>
typedef struct ArrayList {
int *data;
int capacity;
int size;
ArrayList *list;
ArrayList ArrayList_init(int);
int insert(ArrayList *, int , int);
int set(ArrayList*, int, int);
int destroy(ArrayList *);
int print(ArrayList *);
int append(ArrayList *, int);
int valueOf( ArrayList *, int);
int size(ArrayList *);
int capacity(ArrayList *);
} ArrayList;
ArrayList * ArrayList_Init( int n )
{
ArrayList->data = malloc(sizeof(n) * ArrayList->capacity);
}
int append( ArrayList * list, int val )
{
if (list->size >= list->capacity)
return 1;
else
Arraylist->data[list->size++] = value;
return 0;
}
int print( ArrayList * list )
{
printf("%d\n", list->data);
return 0;
}
int set( ArrayList * list, int val, int index )
{
while(index >= list->size)
append(ArrayList, 0);
return 0;
if (index < 0 || index >= size)
return 1;
}
int destroy( ArrayList * list )
{
free(list->data);
return 0;
}
int insert(ArrayList * list, int val, int index)
{
return 0;
}
int valueOf( ArrayList * list, int element )
{
int x;
x = list->data[element];
return x;
}
int size(ArrayList * list)
{
return list->size;
}
int capacity(ArrayList * list)
{
return list->capacity;
}
int main(void)
{
int n = 3;
int i;
int stat; // Error code
int size;
int val = 0;
int capacity;
// allocate list
ArrayList *list = NULL;
list = ArrayList_Init(n);
printf("ArrayList initialized to %d elements\n", n);
printf("Size of List = %d\n", list->size(list));
printf("Capacity of List = %d\n", list->capacity(list));
// Fill initial values
list->set(list, val++, 0);
list->set(list, val++, 1);
list->set(list, val++, 2);
}
Thank you
First of all if you declare a function that returns something it must do so.
I think your ArrayList_Init should more look like this (I am assuming you want to store integers)
ArrayList * ArrayList_Init( int n )
{
ArrayList * list = malloc(ArrayList);
list->data = malloc(sizeof(int) * n);
list->capacity = n;
list->size=0;
return list;
}
In append as well as in Init you are trying to access a type.
Arraylist->data[list->size++] = value;
but it is supposed to be
list->data[list->size++] = value;
For your insert you can do something similiar to the following:
int insert( ArrayList * list, int val ,int position)
{
if (list->size >= list->capacity){
int * temp = malloc(sizeof(int) * list->capacity *2);
int i;
for(i=0;i<position-1;i++){
temp[i]=list->data[i];
}
for(i=postion-1;i<list->size;i++){
temp[i+1]=list->data[i];
}
free(list->data);
list->data=temp;
list->capacity *=2;
}else{
for(i=list->size;i>postion-1;i--){
list->data[i]=list->data[i-1];
}
}
list->data[position-1]=val;
list->size++;
return 1;
}
You probably want to do something similar in append because otherwise you just have a static array. The idea of a vector is that it grows and shrinks automatically.
Edit:
In C you cannot just declare a prototype of a function inside a struct and than access it.
The only way you can do something similar to what you want to do is by storing a pointer to each of the functions inside your struct. Have a look at the following post.
Define functions in structs