Reputation: 5711
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
Upvotes: 0
Views: 69
Reputation: 754010
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;
}
Upvotes: 1
Reputation: 1723
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;
}
Upvotes: 4
Reputation: 6526
#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.
Upvotes: 0
Reputation: 12169
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).
Upvotes: 1