Stack smashing detected, core dumped [closed] - c

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
#include<stdio.h>
#define MAXSIZE 10
#define OK 1
#define NOK 0
int check_validity(int);
void input_array_elements(int,int *);
void Display_array_elements(int,int *);
int main()
{
int array[MAXSIZE];
int i,num,negative_sum=0,positive_sum=0;
float total=0.0,average;
printf("Enter the value of N\n");
scanf("%d",&num);
while(1)
{
int Return_val;
Return_val=check_validity(num);
if(Return_val == OK)
{
printf("sizeof array=%d\n",sizeof(array));
break;
}
else
{
printf("please enter a value <= 10\n");
scanf("%d",&num);
}
}
input_array_elements(num,&array[MAXSIZE]);
Display_array_elements(num,&array[MAXSIZE]);
}
int check_validity(int num)
{
if(num<MAXSIZE)
{
printf("OK\n");
return OK;
}
else
{
printf("NOK\n");
return NOK;
}
}
void input_array_elements(int num,int *array)
{
int i;
for(i=0;i<num;i++)
{
scanf("%d",&array[i]);
}
}
void Display_array_elements(int num,int *array)
{
int i;
for(i=0;i<num;i++)
{
printf("array[%d]=%d\n",i,array[i]);
}
}
What is "stack smashing"? How to solve this problem?
I'm compiling my program and I'm having error:
* stack smashing detected *: ./a.out terminated Segmentation fault (core dumped)
I don't know what I'm doing wrong.

The pointer to &array[MAXSIZE] is a pointer to one beyond the end of the array. That means your functions will start out of bounds of the array which leads to undefined behavior. The system detects is as a "stack smash" and crashes your program.
If you want to pass a pointer to the first element then use either &array[0], or plain array (as that will decay to &array[0]).

Segmentation fault (or stack smashing as you are getting) happens when you try to access a memory that is not accessible to your program or process.
In your function Display_array_elements I guess you are trying to print the array elements. The second argument should provide the address to the beginning of the array.
By passing &array[MAXSIZE] you are already pointing to the last element and then trying to access the other elements on this array, which is beyond valid array bounds. This is the reason for segmentation fault.
Change this call to one of the below
Display_array_elements(num,&array[0]);
OR
Display_array_elements(num,array);

Segmentation error comes when allocated memory space exceeds by a variable. Once variable declared, amount of memory is allocated in the stack.
Your array causing the problem. Hence array is defined to a particular size, next insertions going above the space and try to access the space of onother variable/ instruction.

Related

C- Character Push and Pop operation [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 3 years ago.
Improve this question
Stack create(int c)
{
Stack S=(Stack)malloc(sizeof(struct stack));
S->size=c;
S->top=-1;
S->array=(char *)malloc(sizeof(char)*c);
return S;
}
Stack makeEmpty(void)
{
Stack *S1=create(100);
S1[0]->top=-1;
return S1;
}
char pop(Stack S)
{
return S->array[S->top--];
};
int main(void)
{
Stack *S1;
S1=makeEmpty();
int j;
int k=0;
char result[30];
for(j=0; j<2; j++)
{
char result1=pop(S1);
strcat(result, result1);
k++;
}
}
I skipped some parts, like typedef struct stack Stack;
What I wanted to do was pop out elements from the stack while for-loop works. Then, store those elements in a new array which is result. To check whether it works or not, I printed out but I had a runtime error. How to store the element and how to print it out?
I've made copy&paste of your code, and it doesn't get compiled. I think that
you are either not posting your actually code nor you don't bother to compile and read the compiler warnings. It's rather difficult to help you. Here some things I noticed:
1.
create must return a pointer to Stack, not the object.
Stack *create(int c)
{
Stack *S = malloc(sizeof *S);
S->size=c;
S->top=-1;
S->array = malloc(c);
return S;
}
2.
Same goes for makeEmpty
Stack *makeEmpty(void)
{
Stack *S1=create(100);
S1->top=-1;
return S1;
}
3.
pop should get a pointer to Stack, not the object
char pop(Stack *S)
{
return S->array[S->top--];
};
Here you should check whether there are elements on your stack. int pop(Stack *S, char *val) where it returns 1 and writes on *val on
success, and returns 0 otherwise would be better.
4.
Judging from your pop you are pushing char only. I don't get what you
are trying to do with strcat. Either way, you are doing strcat wrong. You
are declaring a stack with 100 spaces, but you are only declaring 30 spaces
for result. What if you have more than 31 elements on your stack? I know
that you are only inspecting 2 elements but it's easy to overlook that and
expand it to go through all the stack without changing the memory requirements
for result.
Also strcat is a function that works with C-Strings, that means it expects
C-Strings. A C-String must be \0 terminated, yours are not. You have
something that looks like a C-String but it's not. If you insist on using
strcat, the you should do it like this:
for(j=0; j<2; j++)
{
char result1[] = { pop(S1), 0 };
strcat(result, result1);
}

Segmentation fault: 11

I have a function that looks through a number of matches from an array and find all teams in matches, that meet some conditions. When found they need to be assigned to a new array. The new array should be used as an output parameter.
I get segmentation fault: 11 when I call it. I have tried to debug but cannot seem to get why. Following is declared in main:
TEAM team_least_viewers;
double spectators = 99999;
solve_task_four(round, team, &team_least_viewers, &spectators);
And the function itself:
void solve_task_four(ROUND *round, TEAM *team, TEAM *team_least_viewers, double *spectators) {
int i, j, k = 0;
for(i=0; i<ROUNDS_PR_SEASON; i++) {
for(j=0; j<MATCH_PR_ROUND; j++) {
if(round[i].match[j].year == 2015) {
/* Searching for team name in team[]*/
for(k=0; k<NUMBER_OF_TEAMS; k++) {
/* If it matches */
if (round[i].match[j].home_team == team[k].name) {
team[k].spectators_home_last_year += round[i].match[j].spectators;
}
}
}
}
for(k=0; k<NUMBER_OF_TEAMS; k++) {
if(team[k].spectators_home_last_year < *spectators) {
*spectators = team[k].spectators_home_last_year;
}
}
}
}
The structs as requested:
typedef struct {
char weekday[WEEKDAY_SIZE], start_time[START_TIME_SIZE],
home_team[TEAM_SIZE], away_team[TEAM_SIZE];
double spectators;
int day, month, year, round, home_team_score, away_team_score;
} MATCH;
typedef struct {
MATCH match[MATCH_PR_ROUND];
} ROUND;
typedef struct {
char *name;
int points, matches_played,
matches_won, matches_draw, matches_lost,
matches_won_home, matches_won_away,
goals_for, goals_against, goal_difference;
double spectators_home_last_year;
} TEAM;
Any help is much appreciated.
I infer your questions is: How do I figure out what is causing the segmentation fault? If that's right, then one answer is to use a debugger. Another answer would be to add print statements throughout the code. The segfault is almost certainly one of the array indexings, like round[i] or round[i].match[j], so be sure to print the i and j values. You may be indexing past the end of an array or dereferencing a null pointer or an uninitialized pointer, so print the pointer values, like printf("round[%d] at %p\n", i, &round[i]).
SIGSEGV on several operating systems is signal 11, and is delivered to the process on a segmentation fault.
Segmentation faults occur when your program accesses memory in a way which isn't allowed, usually by attempting to dereference a null pointer or running off the end of an array.
In your program, the most likely culprits are are array indexes, round[i].match[j] and team[k]. (Another possibility would be if the spectator argument passed were not a valid location for writing, but this is unlikely in this particular case.) You may wish to insert code/run in a debugger to check whether each access is correct.
In particular, assuming that your ROUNDS_PR_SEASON &c. values are correct, it seems most likely that some round[i].match contains a null, if your round array was not fully initialized.

Passing structures into functions in c [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I want to write a simple c code to create a garden structure,input details like num_animals, type of garden and size of garden.
However, my code is giving me some garbage output.
#include <stdio.h>
#include <string.h>
struct Garden
{
int num_animals;
int size;
char type[10];
};
void Input(struct Garden gardname)
{
printf("\nEnter number of animals\n");
scanf("%d",&gardname.num_animals);
printf("\nEnter size\n");
scanf("%d",&gardname.size);
printf("\nEnter type\n");
scanf("%s",gardname.type);
}
void Output(struct Garden gardname)
{
printf("Num of animals:%d\n",gardname.num_animals);
printf("size:%d\n",gardname.size);
printf("type:%s\n",gardname.type);
}
int main()
{
struct Garden Lumbini;
Input(Lumbini);
Output(Lumbini);
return 0;
}
The functions you have defined, by default use call by value method of passing arguments, which means that although you have Lumbini structure to which you intend to read and write elements, your functions will instead make a copy of Lumbini(in this case gardname), and write to, or print out that copy, not Lumbini. It may lead to duplicate values. I have written the same program using call by reference (note how a pointer to structure is the expected parameter in function, and the reference of lumbini is passed on call). This insures that there are no duplicates, and only the relevant structure (in this case, lumbini) is being manipulated.
#include <stdio.h>
#include <string.h>
struct Garden
{
int num_animals;
int size;
char an_type[10];
};
void Input(struct Garden *gardname)
{
printf("\nEnter number of animals\n");
scanf("%d", &gardname->num_animals);
printf("\nEnter size\n");
scanf("%d", &gardname->size);
printf("\nEnter type\n");
scanf("%s", gardname->an_type);
}
void Output(struct Garden *gardname)
{
printf("Num of animals:%d\n",gardname->num_animals);
printf("size:%d\n",gardname->size);
printf("type:%s\n",gardname->an_type);
}
int main()
{
struct Garden Lumbini;
Input(&Lumbini);
Output(&Lumbini);
return 0;
}
You are getting garbage values because gardname in Output function is a local variable to an uninitialized copy of lumbini structure. When you print out the values of gardname, they will be garbage values as they are not initialized. As the function finishes execution, gardname is destroyed.
Also, instead of writing
scanf("%d",&gardname.num_animals)
you must write
scanf("%d", &gardname->num_animals)
This will read into the address of pointer gardname plus the offset of member num_animals into the structure.

Reading into array [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
Please help, I need to read an input txt file into an array and print it out put somehow I keep getting error message.
#include <stdio.h>
void reading_into_array(int A[]);
#define MAXVALS 100
int
main(int argc, char *argv[]){
int numbers[100], i;
reading_into_array(numbers[MAXVALS]);
for(i = 0; i < 100; i++){
printf("%d", numbers[i]);
}
return 0;
}
/*input information*/
void
reading_into_array(int A[]){
double inp;
int n = 0;
while(scanf("%lf",&inp) == 1){
A[n++] = inp;
}
}
numbers[MAXVALS] is out-of-range and its type doesn't match with the function argument. use numbers instead.
Avoid using values of uninitialized variables having automatic storage duration, which invokes undefined behavior. Initialize numbers like int numbers[100]={0},i;
When calling a function that takes an array as a parameter, you only need to supply the name of the array, e.g. numbers. "numbers[MAXVALS]" would supply the value of the MAXVALth element of this array. This is wrong for two reasons:
the function needs an array, not an element
The array has a size MAXVAL; its elements are counted from zero to MAXVAL-1, so the MAXVALth element does not even exist
If you want floating point numbers in your array, declare the array as double A[MAXVAL] everywhere.
Last note: the reading_into_array function should have a check that it will prevent it from putting more than MAXVAL numbers into the array, or you risk that it will corrupt memory and crash your program.

Allocating memory through calloc in C [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 6 years ago.
Improve this question
I am simply testing what would be the output if I try to dereference a pointer, which points to out of range of dynamically created memory using calloc() and expecting memory fault or some garbage value instead. It is giving 0 as output, which is basic feature of calloc() that it intializes allocated memory with '0', or is it just due to undefined behavior?
#include <stdio.h>
#include <stdlib.h>
int main()
{
int *p = NULL;
p = (int *)calloc(10, 8);
if(p != NULL)
{
printf("\n successfully allocated memory ");
}
else
EXIT_FAILURE;
printf("\n Thirty first element of memory is %d \n",p[30]);
}
Result :
successfully allocated memory
Thirty first element of memory is 0
You are trying to access p + 30 * sizeof(int) which is p + 120 while you have allocated only 8 * 10 = 80 bytes, so max address you can access is p[19]
From a language perspective, accessing out of bounds memory is undefined behavior, meaning that anything can happen.
One possible explanation for that particular behavior is that most operating systems will zero out any memory before they give it to your process, independently of what function you where using internally (this is a security measure, so you can't read data that was used by other processes).
To get garbage data, you usually have to have used and freed the same memory before inside your program (in which case it retains its old value). Or of course, if your index is so far off that you are indexing into a neighboring data structure.
The reason your program didn't just crash is that malloc (and similar functions) usually request much more memory from the os, than what you are requiring and use the surplus memory the next time you call malloc. So from the OS perspective you are accessing valid memory, and there is no reason to terminate your program.
Accessing out of range memory is Undefined Behaviour. Hence the value which you get can be 0 or 1 or Batman
The point is, you cannot ask any explanation or reason for things that are undefined. Anything can happen in such a scenario.
Also, you would get a seg fault if you try to access a memory location which your program is not allowed to access. That may not be the case always when you access out of bounds memory. It can lie well inside the user memory area of the program.
I think windows zeroes a freed page before making available for allocation. Have fun with the code below.
#include<stdio.h>
#include<stdlib.h>
#include <windows.h>
#include <signal.h>
int g = 0;
unsigned long long* p=NULL;
void signal_handler(int ssc)
{
printf("Error %d \n", ssc);
printf("segfault after %llu bytes",g*8);
printf("should i go backwards? press enter");
getch();
g=0;
do
{
printf("Virtual Adress:%llu is %llu\n",p+g,*(p+g) );
Sleep(1);
g--;
}
while(1);
}
int main ()
{
if(SIG_ERR == signal(SIGSEGV, signal_handler) ) {printf("error seting signal handler %d\n",SIGSEGV);}
p = (unsigned long long*)calloc(10,8);
if( p!= NULL)
{
printf("successfully allocated memory\n");
}
else
{
EXIT_FAILURE;
}
do
{
printf("Virtual Adress:%llu is %llu\n",p+g,*(p+g) );
Sleep(2);
g++;
}
while(1);
return 0;
}

Resources