Segmentation fault at passing array of integers to function - c

I have pasted the code here, at the statement *stack_ptr->s3++ = element;
segmentation fault is occurring. Can you please let me know what should I change to eliminate the error?
typedef int stack_elmnt_int;
typedef struct {
stack_elmnt *s1;
stack_elmnt_int *s3;
int length;
int top;
} stack;
int push_stack_int(stack *stack_ptr, stack_elmnt_int element)
{
int i=0;
if (stack_full(stack_ptr))
printf("\nStack is full.");
else{
*stack_ptr->s3++ = element;
}
}
void main()
{
int arr[128], arr_num = sizeof(arr)/sizeof(int);
//after input from user to arr
//partial code pasted here
for(i=0;i<arr_num ;i++)
push_stack_int(&stack_1,arr[i]);
}

statement (*stack_ptr->s3++ = element;) segmentation fault is occuring,
Probably you don't allocate memory for s3.
*stack_ptr->s3++ = element;
^
| assigning to garbage location
Can you please let me know what should I change to eliminate the error?
In main() function after declaration of stack_1 allocate memory for s3 ( you should allocate memory for s1 also ), do like:
stack_1.s3 = calloc(MAX_NUMBER_OF_ELEMENT, sizeof( stack_elmnt_int));
Additionally, you should not increment s3 pointer. (you will loss starting address) do like:
stack_ptr->s3[top++] = element;

You need to check that both stack_ptr and stack_ptr->s3 have had memory allocated and been initialized previously in your code.

Related

C - Free a specific struct inside an array inside a stack

During my stack building I encountered a problem with free an element inside an array in my Pop function.
This is the code:
Element Pop(Stack *stackPtr)
{
Element temp = stackPtr->content[stackPtr->size-1];
Element* newE = (Element*)realloc(stackPtr->content,(stackPtr->size-1)*sizeof(Element));
free(stackPtr->content[stackPtr->size-1]);
stackPtr->content=newE;
stackPtr->size--;
return temp;
}
And for some reason the free(stackPtr->content[stackPtr->size-1]); do an error every time.
Why is that and how do I fix that?
Thanks.
This is the whole code:
#include <stdio.h>
#include <malloc.h>
#include <string.h>
#include <stdlib.h>
typedef struct
{
int kind; // boolean
int num;
char ch;
} Element;
typedef struct
{
Element *content;
int size;
} Stack;
void Init(Stack* stackPtr)
{
stackPtr->content = (Element*)malloc(1*sizeof(Element));
stackPtr->content[0].kind = 3;
stackPtr->content[0].ch = 'a';
stackPtr->content[0].num = -2;
stackPtr->size = 1;
}
void Push(Stack* stackPtr, Element element)
{
stackPtr->content = (Element*)realloc(stackPtr->content,((stackPtr->size)+1)*sizeof(Element));
stackPtr->size++;
stackPtr->content[stackPtr->size-1] = element;
}
Element Pop(Stack *stackPtr)
{
Element temp = stackPtr->content[stackPtr->size-1];
Element* newE = (Element*)realloc(stackPtr->content,(stackPtr->size-1)*sizeof(Element*));
free(stackPtr->content[stackPtr->size-1]);
stackPtr->content=newE;
stackPtr->size--;
return temp;
}
Element Top(Stack *stackPtr)
{
return stackPtr->content[stackPtr->size-1];
}
Of course this crashes - you just have reallocated the data which stackPtr->content was pointing to, so the array access is now invalid.
Since you already reallocated, and you are returning the removed element, that call to free is pointless though, and illegal in multiple ways. The memory is already free'd, but not only that, it was never a pointer to begin with.
Also be aware which parameters to realloc are valid. If your Pop function "removes" the last element, you would try to realloc to a size of zero, which isn't legal.
And you should put in a defensive check anyway, ensure that nobody is trying to pop from an already empty stack.
Since content[] is an array of pointers, the realloc should use sizeof(Element*), not sizeof(Element), especially if sizeof(Element) less than sizeof(*).
Edited to reflect intent of Comments:
Element *Pop(Stack *stackPtr)
{
if (stackPtr->size==0) return NULL;
Element temp = stackPtr->content[stackPtr->size-1];
stackPtr->size--;
if (stackPtr->size==0) free(stackPtr->content)
else {
Element* newE = (Element*)realloc(stackPtr->content,stackPtr->size)*sizeof(Element));
stackPtr->content=newE;
}
Element* rslt = malloc(sizeof(Element);
memcpy(rslt,&temp,sizeof(Element));
return rslt;
}
In the using code the pointer returned would need to be free'd separately. I view this as safer than assuming the compiler will copy the auto allocation of temp into the return value, anyways.

Accessing data in array segmentation fault

I'm encountering a segmentation fault in my program and I'm pretty sure it's a silly mistake! When I try to access data in my arrays of structs I get a segemtentation fault.
struct block {
int validBit;
int tag;
unsigned long data;
};
typedef struct block block_t;
struct set{
block_t *blocks;
int tst;
};
typedef struct set set_t;
struct cache{
//bunch of variables I have left out for this question
set_t *set;
};
typedef struct cache cache_t;
So the allocation of memory to these are
cache_t *cache = NULL;
cache = malloc(sizeof(*cache);
if(cache == NULL){
fprintf(stdout,"Could not allocate memory for cache!");
}
cache->set = malloc(16 * sizeof(*cache->set));
if(cache->set == NULL){
fprintf(stdout,"Could not allocate memory for cache->set!");
}
cache->set->blocks = malloc(2 * sizeof(*cache->set->blocks));
if(cache->set->blocks == NULL){
fprintf(stdout,"Could not allocate memory for cache->set->blocks!");
}
The cache holds an array of sets with 16 elements. The cache->sets holds an array of blocks with 2 elements.
When I try to set the value of variables inside a block struct a segmentation error arises.
cache->set[0].blocks[0].tag = 1; //This works
cache->set[0].blocks[1].tag = 2; //This works
cache->set[1].blocks[0].tag = 3; //Segmentation fault
EDIT: It seems there is a problem with the variable "tag" inside blocks. If i assign a value to validbit in set[1] it does not produce a segmentation fault.
cache->set[1].blocks[0].validBit = 3; // This works
cache->set[1].blocks[0].tag = 3; //does not work
So it seems to be an issue with the tag variable? Makes no sense to me
Thanks in advance :)
You are not allocating memory for your "block_t" beyond set[0].
Roughly, you should be doing something along these lines:
cache = malloc(sizeof *cache);
cache->set = malloc(num_sets * sizeof *cache->set);
for (i = 0; i < num_sets; i++) {
cache->set[i].blocks = malloc(...);
}

error of dereferencing pointer, in struct

I tried all the solutions on the site and didn't manage to fix this problem
i got a declared struct in my header
struct _fileNew;
typedef struct _fileNew fileNew;
in my source file I defined fileNew
struct _fileNew
{
char chars[];
};
now in my main i tried printing something inside the struct
fileNew* blu;
int i;
for ( i = 0; i < 10; i++)
{
blu->chars[i] = 'b';
}
printf("%s", blu->chars);
and i got
error: dereferencing pointer to incomplete type
I ran a debug and i saw that the cahrs was filled correctly but it won't print it. and I doin something wrong in the source file while defining the fileNew.?
thanks!
You need to allocate a memory block for the structure in heap and assign its address to Your pointer.
In C every string ends with a '\0' (string terminator), so You need to add it also.
#include <stdio.h>
#include <stdlib.h>
#define MAX_FILE_SIZE 128
struct _fileNew;
typedef struct _fileNew fileNew;
struct _fileNew
{
char chars[MAX_FILE_SIZE];
};
int main()
{
fileNew *blu = malloc(sizeof *blu);
int i;
for (i = 0; i < 10; i++)
{
blu->chars[i] = 'b';
}
blu->chars[i] = '\0';
printf("%s", blu->chars);
return 0;
}
You only have a pointer that is not actually pointing to anything and need to allocate size for the char[]. In main you need to assign the pointer to point at the declared struct OR use malloc as the other answers suggest:
static fileNew blu;
fileNew *p_blu = &blu;
...
p_blu->chars[i] = 'b';

memcpy_ssse3 segmentation fault

SIZE = 2*1024*1024*1024;
struct
{
char array[SIZE];
} s1;
char *seq;
File *sp;
int i = 0;
EoFReached = 0;
memset(array,0,SIZE*sizeof(char));
while(EoFReached == 0) {
getseq(sp, seq, EoFReached);
memcpy(&(s1->array[i]),seq, seqlen);
i = i + seqlen;
}
After i value of 630511104 memcpy overwrites some values with some wrong values in the beginning of the array itself but at same time ending values are correct.
So tired to allocate memory dynamically instead of static allocation, using malloc.
But got segmentation falut after 630511104
with error message in gdb as
__memcpy_ssse3 () at ..sysdeps/x86_64/multiarch/memcpy-ssse3.S:"
../sysdeps/x86_64/multiarch/memcpy-ssse3.S: No such file or
directory.
You put the 2 gig big s1 on the stack wich is not that big. Try to allocate s1 with new instead:
struct fred { char array[SIZE]; }; fred * s1 = new fred;

what is causing segmentation fault in c code, dynamic allocation accross functions

I am trying to have dynamically allocate arrays of structures and perform operations on them but i keep running into segmentation faults. could someone help me out?
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
void *malloc(size_t size);
typedef struct {
double x;
double y;
} coords;
struct figure {
char fig_name[128];
int coordcount, size_tracker;
coords *pointer;
} fig;
void init_fig(int n, struct figure **point)
{
printf("%u\n", sizeof(coords));
point[n]->pointer = malloc(sizeof(coords) * 20); <-------SEGFAULT
if (point[n]->pointer == NULL){
exit(-1);
}
point[n]->pointer[19].x = 2;
point[n]->pointer[0].x = 1;
point[n]->pointer[0].y = 2;
point[n]->pointer[7].x = 100;
}
int main()
{
int numfigs = 1;
struct figure * point;
point = malloc(sizeof(struct figure) * 16);
point = &fig;
point[1].coordcount = 1;
init_fig(numfigs, &point);
return 0;
}
I labelled where the first seg fault occurs, (used ddd). what i dont get is that i can manipulate point[1] in main but not in any other function.
I agree with #Maxim Skurydin.
Nevertheless I'd like to explain your mistake in some more details.
Reading your init_fig one assumes that the parameter you pass struct figure **point - is actually array of pointers to struct figure. And this function accesses its n'th element.
However in your main you do something else. You allocate an array of struct figure, and your point variable points to its head. Then you take the address of this local variable and call your init_fig.
Here's the problem. init_fig assumes that you pass it an array of pointers, whereas actually this "array" consists of a single element only: the local point variable declared in main.
EDIT:
How to do this properly.
Leave main intact, fix init_fig.
This means that actually there's an array of figure structs. Means - a single memory block, interpreted as an array of consequent structs.
void init_fig(int n, struct figure *point)
{
printf("%u\n", sizeof(coords));
point[n].pointer = malloc(sizeof(coords) * 20); <-------SEGFAULT
if (point[n].pointer == NULL){
exit(-1);
}
point[n].pointer[19].x = 2;
point[n].pointer[0].x = 1;
point[n].pointer[0].y = 2;
point[n].pointer[7].x = 100;
}
Leave init_fig intact. Fix main.
This means that we actually should allocate an array of pointers, every such a pointer should point to an allocated point structure.
int main()
{
int numfigs = 1;
struct figure ** point;
point = malloc(sizeof(struct figure*) * 16);
for (i = 0; i < 16; i++)
point[i] = malloc(sizeof(struct figure));
point[1].coordcount = 1;
init_fig(numfigs, &point);
return 0;
}
You allocate memory and store the pointer in point but then you forget that pointer when you assign &fig to it.
point = malloc(sizeof(struct figure) * 16);
point = &fig;
So, you are essentially trying to write fig[1], that does not make sense.
struct figure * point;
point = malloc(sizeof(struct figure) * 16);
here point is pointer pointing to memory of 16 structures in heap
but in the next line you have done this
point = &fig;
so its memory leak and also point is not pointing to that allocated region anymore
and also init_fig should be like this
void init_fig(int n, struct figure **point)
It's the problem of segfault
Eliminate this line point = &fig;
and modify the function:
void init_fig(int n, struct figure *point)
{
...
point[n].pointer = (coords*) malloc(sizeof(coords) * 20);
...
}
since you should pass an array of structs and not an array of pointers.
Also, add a third parameter to the init_fig function so you can pass the size of the array of points that you want to create. Like :
void init_fig(int n, struct figure *point, int size)
{
...
point[n].pointer = (coords*) malloc(sizeof(coords) * size);
...
}
Therefore, making the function more reusable.
Modify also the call to that function:
init_fig(numfigs, &point); to init_fig(numfigs, point);

Resources