The following code is generating pointer warnings and I am not sure how to fix it?
gcc -std=c11 -pg -g3 -ggdb -W -Wall -lefence -I. -o main.o -c main.c
main.c: In function ‘push_state’:
main.c:15:16: warning: assignment makes pointer from integer without a cast [-Wint-conversion]
*++s->point = s->top;
^
main.c: In function ‘pop_state’:
main.c:19:11: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
s->top=*s->point--;
^
#include <stdio.h>
typedef struct stack{
int **point; // pointer to location in memory
int *memory[24]; // stack memory
int top;
int i;
}Stack;
void push_state(Stack *s){
s->top=s->i++;
*++s->point = s->top;
};
void pop_state(Stack *s){
s->top = *s->point--;
};
void get_top(Stack *s){
printf("Stack top: %d\n",s->top);
};
void start(){
Stack s;
s.point=&s.memory[0];
s.i=0;
push_state(&s);
get_top(&s);
pop_state(&s);
get_top(&s);
}
int main( int argc, char *argv[] ) {
start();
return 0;
}
As written in the warning, t->top is a integer but *++s->point is a pointer, so you cant convert integer to pointer.
Maybe you want this;
typedef struct stack{
int **point; // pointer to location in memory
int *memory[24]; // stack memory
int *top;
int i;
}Stack;
void push_state(Stack *s){
s->top=s->memory[s->i++];
*++s->point = s->top;
};
I am posting a solution to my problem:
The problem was that s.point=&s.memory[0]; was not correct it should be s.point=s.memory; also **point was not correct it should be *point and *memory[24]; should be *memory and declared dynamically. Thanks Jonathan Leffler for making me go back and rethink it by removing the extra * from **point.
#include <stdio.h>
#include <stdlib.h>
#define push(s) (*++s->point = s->top)
#define pop(s) (*s->point--)
#define look(s) (*s->point)
#define MALLOC(p,s) if(((p) = malloc(s * sizeof(p))) == NULL){ exit(EXIT_FAILURE); }
typedef struct stack{
int *point; // pointer to location in memory
int *memory; // stack memory
int top;
int i;
}Stack;
void push_state(Stack *s){
++(s->top);
push(s);
};
void pop_state(Stack *s){
s->top = pop(s);
};
void look_top(Stack *s){
printf("look %d, Stack top: %d\n",look(s), s->top);
};
void start(){
Stack s;
s.top=0;
MALLOC(s.memory,24);
//s.point=&s.memory[0]; <- wrong assignment
s.point=s.memory;
push_state(&s);
push_state(&s);
push_state(&s);
look_top(&s);
pop_state(&s);
look_top(&s);
pop_state(&s);
look_top(&s);
push_state(&s);
look_top(&s);
}
int main( int argc, char *argv[] ) {
start();
return 0;
}
Related
Can anyone please explain here what is the issue in the below code because of that it is not producing any errors as well as any output?
#include <stdio.h>
#include <stdlib.h>
typedef struct Stack{
int size;
int top;
int data;
int *arr;
} Stack;
void push( Stack*s , int data)
{
s->top++;
s->arr[s->top] = data;
}
int main()
{
struct Stack *s;
s->size = 100;
s->top = -1;
s->arr = (int* ) malloc (s->size* sizeof(int));
push( s, 180);
}
this is because you write struct Stack *s; which is just a wild pointer pointing to some space in memory with no reserved space, so you should do instead :
struct Stack *s = (struct Stack* ) malloc (sizeof(struct Stack));
to reserve space for your wild pointer.
even my compiler gave me this warning, so make sure to turn on all compiler warnings on yours.
Variable 's' is uninitialized when used here
this is the full code with only this small modification:
#include <stdio.h>
#include <stdlib.h>
typedef struct Stack{
int size;
int top;
int data;
int *arr;
} Stack;
void push( Stack*s , int data)
{
s->top++;
s->arr[s->top] = data;
}
int main()
{
//struct Stack *s = (struct Stack* ) malloc (sizeof(struct Stack));
struct Stack *s;
s->size = 100;
s->top = -1;
s->arr = (int* ) malloc (s->size* sizeof(int));
push( s, 180);
printf("stack top data = %d\n", s->arr[s->top]);
}
and this is the output:
stack top data = 180
I am trying to implement on my own (in order to understand it better) the Stack data structure in C language.
Here is what I've got so far:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct stack{
//Data_Strucure: Stack of intgers
int *stack;
int size_of_stack;
int elem_in_stack;
};
struct stack *creat_stack(unsigned int);
int push(struct stack *, int);
int pop(struct stack *);
int empty(struct stack *);
int peek(struct stack *);
int main(int argc, char *argv[]){
int new_elem = 13;
struct stack *new_stack = creat_stack(5);
printf("%d %d\n", new_stack->size_of_stack, new_stack->elem_in_stack);
//Crashes from here
push(new_stack, new_elem);
printf("%d\n", new_stack->stack[new_stack->size_of_stack]);
}
struct stack *creat_stack(unsigned int size){
struct stack tmp;
struct stack *ret_stack = &tmp;
if((ret_stack->stack = malloc(sizeof(int) * size)) == NULL){
fprintf(stderr, "Unable to allocate memory for the Stack.\n");
exit(1);
}
ret_stack->size_of_stack = size;
ret_stack->elem_in_stack = 0;
return ret_stack;
}
int push(struct stack *stack, int nw_elem){
int pos = stack->size_of_stack - stack->elem_in_stack;
if(stack->size_of_stack == 0)
return 1;
stack->stack[pos] = nw_elem;
}
The compiler returns me no error. Though I don't understand why it crashes after push() is called.
Please, if possible, instead of solution code, can you just tell me where the error is? This way I can understand how it effect the whole program and try to solve it on my own (so next time won't happen again).
Thanks is advance for any of your usefull answers.
At least the function creat_stack is incorrect.
struct stack *creat_stack(unsigned int size){
struct stack tmp;
struct stack *ret_stack = &tmp;
//...
return ret_stack;
}
It returns a pointer to the local object tmp that will not be alive after exiting the function. So the returned pointer will be invalid and dereferencing such a pointer invokes undefined behavior.
Instead you could return the object itself from the function. That is the function declaration could look like
struct stack creat_stack(unsigned int size);
And in main you can write
struct stack new_stack = creat_stack(5);
Also the function push does not change the data member elem_in_stack And again it invokes undefined behavior because when elem_in_stack is equal to 0 then the function tries to write to memory outside the dynamically allocated array. That is in this case pos is equal to size_of_stack.
int push(struct stack *stack, int nw_elem){
int pos = stack->size_of_stack - stack->elem_in_stack;
if(stack->size_of_stack == 0)
return 1;
stack->stack[pos] = nw_elem;
}
I'm trying to build a stack using a linked list but I get a EXC_BAD_ACCESS error in my linkedListStackInit method;
LinkedList.h
#ifndef LinkedListStack_h
#define LinkedListStack_h
#ifndef __TYPE
#define __TYPE
#define TYPE int
#define TYPE_SIZE sizeof(int)
#endif
#include <stdio.h>
struct Link;
struct LinkedListStack;
void linkedListStackInit(struct LinkedListStack *s);
void push(struct LinkedListStack *s, TYPE data);
void pop(struct LinkedListStack *s);
TYPE top(struct LinkedListStack *s);
int isEmpty(struct LinkedListStack *s);
#endif
LinkedList.c
#include <stdlib.h>
#include "LinkedListStack.h"
struct Link {
TYPE value;
struct Link *next;
};
struct LinkedListStack {
struct Link *firstLink;
};
void linkedListStackInit(struct LinkedListStack *s) {
s->firstLink = 0;
}
void push(struct LinkedListStack *s, TYPE data) {
struct Link *newLink = malloc(sizeof(struct Link));
// Assert?
newLink->next = s->firstLink;
newLink->value = data;
s->firstLink = newLink;
}
void pop(struct LinkedListStack *s) {
struct Link *temp = s->firstLink;
s->firstLink = s->firstLink->next;
free(temp);
}
TYPE top(struct LinkedListStack *s) {
return s->firstLink->value;
}
int isEmpty(struct LinkedListStack *s) {
if(s == NULL) {
return 0;
}
else {
return 1;
}
}
main.c
#include <stdio.h>
#include <stdlib.h>
#include "LinkedListStack.h"
int main(int argc, const char * argv[]) {
struct LinkedListStack *s;
linkedListStackInit(s);
return 0;
}
From your main method you are calling the function linkedListStackInit and passing stack (s) to it. But you haven't allocated memory to s before passing it to the linkedListStackInit function. The function linkedListStackInit doesn't allocate the memory either and tries to assign a value to its "firstlink" member. Try to do the following in your linkedListStackInit function and see if you can proceed further.
s = malloc(sizeof(struct LinkedListStack));
I dont understand why assigning 'root' to equal to 'trieu' would be an incompatible pointer :/
#include <stdio.h>
#include <stdlib.h>
struct uniform {
char size;
int number;
struct uniform *ext;
};
struct uniform *trieu;
struct unifrom *root;
int main(void) {
trieu = malloc(sizeof(struct uniform));
root = trieu;
...
trieu = root;
When I compile it with gcc it gives me:
program.c: In function ‘main’:
program.c:15:7: warning: assignment from incompatible pointer type
root = trieu;
^
program.c:57:8: warning: assignment from incompatible pointer type
trieu = root;
It worked before in another program I made with:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct ll {
char store;
struct ll *ext;
};
struct ll *trieu;
struct ll *root;
int main(int argc, char* argv[]) {
trieu = malloc(sizeof(struct ll));
root = trieu;
...
You have a typo. Use struct uniform *root; instead of struct unifrom *root;.
First of all when using malloc to allocate a new sturct you need to cast the return pointer.
struct uniform {
char size;
int number;
struct uniform *ext;
}UNIFORM;
trieu = (UNIFORM*)malloc(sizeof(UNIFORM));
I'm trying to get the hang of c and I can't figure out why this code is producing a segfault.
// In src/test.c
#include <stdio.h>
typedef struct {
int length;
int *arr[1000];
} Stack;
void push(Stack *stack, int el) {
(*stack->arr)[stack->length++] = el;
}
int pop(Stack *stack) {
return (*stack->arr)[--stack->length];
}
int main(int argc, char* argv[]) {
Stack stack;
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
Then I compile and run:
$ gcc src/test.c -o test && ./test
[1] 79484 segmentation fault ./test
You have a few problems.
Like others have mentioned, your int length struct member is never set to zero and thus could contain anything.
You must set the length to 0.
Second, int *arr[1000] is an array of integer pointers. So simply assigning an int to a particular array position is wrong.
You want something more like this:
// In src/test.c
#include <stdio.h>
typedef struct {
int length;
int arr[1000]; // Code change (create an array of integers)
} Stack;
void push(Stack *stack, int el) {
stack->arr[stack->length++] = el; // Code change (no need for additional
// structure member dereference).
}
int pop(Stack *stack) {
return stack->arr[--stack->length]; // Code change (no need for additional
// structure member dereference).
}
int main(int argc, char* argv[]) {
Stack stack;
stack.length = 0; // Code change (set the starting length value to 0)
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
In your structure, "length" is never initialized, so it contains garbage. WHen you then reference:
(*stack->arr)[stack->length++]
it is indexing memory at an undefined location. So, you need some function, like "init_stack()" to initialize the structs data members to well known values (like zero).
The type of the array in the structure is wrong; it should be int arr[1000];.
As written, you're using uninitialized variables all over the place; neither the length nor any of the pointers in your arr are set to anything reliable (though the pointers should be plain int anyway). Because you have pointers instead of int in your stack, you have a very complex expression to access the stack (the (*stack->arr)[stack->length++], etc), which should be much simpler, as in this rewritten code below.
#include <stdio.h>
typedef struct
{
int length;
int arr[1000];
} Stack;
void push(Stack *stack, int el)
{
stack->arr[stack->length++] = el;
}
int pop(Stack *stack)
{
return stack->arr[--stack->length];
}
int main(void)
{
Stack stack = { 0, { 0 } };
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
#include <stdio.h>
typedef struct {
int length;
int arr[1000];
} Stack;
void push(Stack *stack, int el) {
(stack->arr)[stack->length++] = el;
}
int pop(Stack *stack) {
return (stack->arr)[--stack->length];
}
int main(int argc, char* argv[]) {
Stack stack;
memset(&stack,0,sizeof(Stack));
push(&stack, 5);
printf("%d\n", pop(&stack));
return 0;
}
The thumb rule is allocate memory before accessing it.