I don't know what is causing a segmentation fault - c

I am trying to create a simple "diary", where you add workers and then write them how many hours they have worked. But every time I get to the switch statement, I get a segmentation fault. I don't know what is causing it and my knowledge is not yet on the level where I can find it myself.
The code:
include <stdio.h>
include <stdlib.h>
include <string.h>
int vybera(int pocet){
int vyber;
int i;
printf("\nKtery zamestnanec?\n");
for(i = 0; i < pocet; i++){
printf("%d\n", i + 1);
}
scanf("%d", vyber);
return vyber;
}
int main(int argc, char** argv) {
int worker;
int pocet;
int i;
int vyber;
int pomoc;
int odprac = 0;
printf("Kolik zamestnancu chcete pridat: ");
scanf("%d%*c", &pocet);
char workforce[pocet][100];
printf("Zadejte %d jmen: \n", pocet);
for(i = 0; i < pocet; i++){
gets(workforce[i]);
}
for(i = 0; i < pocet; i++){
printf("%s\n", workforce[i]);
}
vyber = vybera(pocet);
switch(vyber){
case 1:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 2:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 3:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 4:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
case 5:
worker = vyber - 1;
printf("Vybrali jste %s.\n", workforce[worker]);
printf("Pocet odprac. hodin: ");
scanf("%d", pomoc);
odprac += pomoc;
strcat(workforce[worker], (", %c", odprac + '0'));
break;
default:
printf("Spatny vyber.\n");
}
for(i = 0; i < pocet; i++){
printf("%s\n", workforce[i]);
}
return (EXIT_SUCCESS);
}
I am really at my wits end, and need every help I can get. The reason why I'm posting this even though there are many question on the segementation fault topic is that none of them are using my code. I appreciate any help and all of your patience.
EDIT: I'm from Czechia, hence why most of my variables and all my printf outputs are in czech. Just FYI.

change: scanf("%d", vyber); to scanf("%d", &vyber) do the same with pomoc;
Explanation: Because vyber variable is int you need to explicitly pass the address value with "&" ampersand, unlike a string(which implicitly passes its address). The segmentation fault indicates you are trying to access a memory which doesn't belong to you. In this case vyber.

You've already been told where the problem is, but let me briefly mention how you can find the (next) problem yourself. Basically, there are (at least) three ways:
Use a debugger to run your program line by line until it crashes. A debugger will also let you stop the program and examine the values of any variables to see what the code is actually doing.
You haven't told us what OS, compiler and IDE (if any) you're using, so I can't recommend any specific debugger (and in any case that's really not on-topic for SO), but there almost certainly is a debugger available for your system, whatever it is. Learning how to use a debugger takes a little effort, but it's definitely worth it.
If you can't or don't want to use a debugger for some reason, you can do "poor man's debugging" by adding printf() statements into your code that show what's happening. That way, you can see how far the program gets before crashing, and you can also print out the values of variables to get a better idea of what's happening.
I would recommend printing to the standard error stream (with fprintf(stderr, "...")), since it won't interfere with normal output of the program, and since the error stream will be automatically flushed every time you print to it, so that there's no risk of buffered output being lost if the program crashes.
A useful trick is to prefix such debugging print statements with if (DEBUG), like this:
if (DEBUG) fprintf(stderr, "This is an example of debugging output.\n");
Then, at the top of your program, include a line like:
#define DEBUG 1
That way, you can easily turn the debugging output off by changing the 1 to a 0. (There are also more advanced ways to change the definition at compile time, or to configure your IDE to change it depending on the build target, but that's outside the scope of the answer.)
Finally, you can do "bisection debugging". Basically, make a copy of your program (or, better yet, commit it into your version control system) and start removing parts of the code until the problem stops happening. At that point, you'll know that the problem is related to something in the last piece of code you removed. You can then undo the most recent change, and remove something else, and keep doing that until you've reduced your program to the simplest possible example that still demonstrates the problem.
At that point, it should be easy to see what the problem is, since you no longer have any irrelevant code left to distract you. Or, if not, at least you have a short piece of code that cleanly demonstrates the problem and which you can post on Stack Overflow to ask for help. :)

scanf("%d", pomoc);
This is incorrect syntax for the scanf() function. It should be:
scanf("%d", &pomoc);
This same error is replicated in the input statement for vyber
scanf("%d", &vyber)
This happens because you are trying to access an out-of bounds location in memory with the scanf() function. Since you don't reference the variable vyber and pomoc, the compiler tries to access the memory spot at an address equal to the variable stored in vyber and pomoc, rather than the memory location of these respective variables. This goes into undefined behavior, which is why you get a seg-fault.

Related

FreeRTOS freezes

I have a simple FreeRTOS programm and basically I need to calculate the time it takes to run for a different number of iterations.
The problem is that it just freezes and doesn't execute anymore though the iterations are not complete yet and I need it to succesfully come to vTaskEndScheduler() to terminate so I can calculate the time correctly. What could be a reason?
Freeze screenshot
void Task1() {
for (int i = 0; i < 100; i++)
{
printf("This is task 1 ");
printf("Iteration number ");
printf("%d", i);
printf("\n");
vTaskDelay(100);
}
vTaskEndScheduler();
};
void Task2() {
for (int i = 0; i < 100; i++) {
printf("This is task 2 ");
printf("Iteration number ");
printf("%d", i);
printf("\n");
vTaskDelay(100);
}
vTaskEndScheduler();
};
void main_blinky(void)
{
enableFlushAfterPrintf();
xTaskCreate(Task1, (signed char*) "t1", 100, NULL, 1, NULL);
xTaskCreate(Task2, (signed char*) "t2", 100, NULL, 1, NULL);
vTaskStartScheduler();
}
Just at a glance, without knowing anything about your system, I would GUESS printf() is causing the problem. How is it implemented? Is it thread safe? Do your tasks have enough stack space for its stack requirements, which can be substantial depending on the library you are using: https://freertos.org/Stacks-and-stack-overflow-checking.html
See notes in the (free but somewhat out of date) book (https://freertos.org/Documentation/RTOS_book.html) ref printf.
You must first choose appropriate stack for task and to be sure it's accessible by heap size in run-time, after that then i think
problem may is in printf() method and the way that's implemented.

How to find the problems of reallocation when it is not done

Consider the following code:
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#define MAX_NUM 5
#define MAX_INCR 5
int main(void)
{
char check = 'y';
int max_number = MAX_NUM;
double *array_input = NULL;
int i = 0;
double buffer = 0.0;
int count = 0;
array_input = malloc(5 * (sizeof(double)));
printf("Please enter the numbers into the array: ");
for(i = 0; i < max_number; i++)
{
++count;
scanf("%lf", &buffer);
*(array_input + i) = buffer;
if(count == max_number)
{
printf("\nDo you want to input more?(y/n) ");
fflush(stdin);
if((check = tolower(getchar())) == 'y')
{
max_number += MAX_INCR;
//realloc(array_input, max_number);
continue;
}
}
}
for(int j = 0; j < max_number; j++)
{
printf("\nThe value is: %lf", *(array_input + j));
}
return 0;
}
(freeing the memory is not done to keep the code consise)
Now, the reallocation is not done in here deliberately but the output of the program is exactly what it should be.
e.g. 5.3, 4.2, 5.6. 7.4, 3, 2, 4, 5, 6, 7.8, the program outputs these numbers as it is, like it should.
How to figure out that there's a possible error in this program?(Example: Someone is given the program but the programmer forgot the reallocation part, it may later cause problems, right?)
The problem with "undefined behaviour" is that you never know. In many cases, just like yours, the program apparently behaves normal, but once you change a little bit, it suddenly crashes, even though the change itself is done correctly. Such bugs often cause security holes, since hackers can exploit them to run their own code.
There are tools to find bugs like that, e.g. http://valgrind.org/
You will never know until exception occurs. That is why people do implement various of testing codes including unit testing and function testing, etc...
Those testings enhance its reliability and quality.
Codes which has security holes are the same.
Programmers who coded could believe that the programmed code is very solid. For example, like the developers who developed remote-drive using network connection secured. However, hackers study the weakness and try many attempts to find the weakness of the system and finally it breaks. After coder finds out its weakness, programmers improve their code from the defect. This is why cyber attack is called spear (who try to attack) and shield (who try to defense).
There are no perfect code. Once it finds its bug, it is needed to improve its quality.

Galton Box/Bean Machine-C

I want to code a simple bean machine program. The program will accept user input for the number of balls and the number of slots, and will calculate the path of each ball. The number of balls in each slot will be printed as a histogram as well.
I tried my best to keep the code short and sweet, yet the best I have managed is 112 lines long. When I ran my code, I received no errors. However, the output seems to have run into some sort of an infinity loop (The '#' symbol which was used to represent numbers in the histogram keeps on printing forever for some reason unknown to me).
Apparently, there is something wrong with my logic somewhere... or a silly little mistake in syntax(but it would have shown up as error, wouldn't it?)... In a nutshell, I cannot figure out exactly what is the problem. (I attempted to walk through the whole code process from start to finish, but my mind kept getting tangled up somewhere in the middle of the code, nowhere near the end of the code either).
Where exactly does my logic go wrong?(Or have I taken the wrong approach to the whole problem?) I do not wish to know the correct code, so that I am able to learn during the whole process of re-editing my code.
Any help (hopefully no model-code answers though), even as a single comment, is tremendously appreciated! :)
This is my code:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <conio.h>
#include <stdbool.h>
#include <time.h>
//Pls excuse my extensive use of libraries even though I don't really use them
int intchecker(float x)
{
if (floor(x)==x && ceilf(x)==x)
{
return 0;
}
else {
return 1;
}
}
int main(){
char line[] = " +----+----+----+----+----+----+----+----+----+----+---+";
char numbers[] = " 0 5 10 15 20 25 30 35 40 45 50";
float balls,slots;
int slotarry[9],tlevel,ballnum,column,lcounter=0,slotsduplicate=1,y;//tlevel-number of levels in the triangle
srand(time(NULL));
int r;
printf("==========================================================\nGalton Box Simulation Machine\n==========================================================\n");
printf("Enter the number of balls [5-100]: ");
scanf("%f",&balls);
while (balls>100 || balls<5) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
while (intchecker(balls)==1) {
printf("\nInput is not an integer. Please try again.");
printf("\nEnter the number of balls [5-100]: ");
scanf("%f",&balls);
}
printf("Enter the number of slots [2-10] : ");
scanf("%f",&slots);
while (slots>10 || slots<2) {
printf("\nInput is not within the range. Please try again.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
while (intchecker(slots)==1) {
printf("\nHow can there be a fraction of a slot? Please re-enter slot number.");
printf("\nEnter the number of slots [2-10] : ");
scanf("%f",&slots);
}
tlevel=slots-1;
for(ballnum=1,column=0;balls>0;balls--,ballnum++,column++){
if (column%5==0){
printf("\n");
}
if (ballnum<10){
printf("[0%d]",ballnum);
}
else{
printf("[%d]",ballnum);
}
for(;tlevel>0;tlevel--){
r = rand() % 2;
if (r==0){
printf("R");
}
else {
printf("L");
lcounter++;
}
}
slotarry[lcounter]++;
tlevel=slots-1;
lcounter=0;
printf(" ");
}
printf("\n\n%s",numbers);
printf("%s",line);
char line2[] = "\n +----+----+----+----+----+----+----+----+----+----+---+";
for(;slotsduplicate<=slots;slotsduplicate++){
if (slotsduplicate<10){
printf("0%d|",slotsduplicate);
}
else{
printf("%d|",slotsduplicate);
}
y=slotarry[slotsduplicate];
if (y==0){
printf(" 0");
}
else{
for (;y>0;y--){
printf("#");
}
printf(" %d",slotarry[slotsduplicate]);
}
printf("%s",line2);
}
return 0;
}
Note:This is not completely error-free. This is just my first draft. I just wish to find out why there is an infinite loop.
Here's how I found the problem. First of all, I think it is a bit of a code smell to have a for loop without anything in the initial assignment section. Couple that with the fact that it seems to print # forever, and it looks like y has a garbage value at the beginning of the loop to print the #s.
So I ran your code in the debugger and paused it when it started printing loads of hashes. I checked the value of y and sure enough it was some unfeasibly high number.
Then I checked where y comes from and found you get it from slotarray. I printed it in the debugger and found that all the values in it were unfeasibly high or massively negative numbers. Obviously, slotarray wasn't being initialised correctly, so I looked for where it was initialised and bingo!
Stack variables (of which slotarray is one) must be explicitly initialised in C. I fixed your code with a call to memset.
The whole debugging process I have just outlined took something less than a minute.
ETA As #EOF points out, there is another bug in that slotarray is defined to contain nine slots (indexed 0 - 8) but you allow people to enter 10 slots. This is a buffer overflow bug.

I need to type "exit" after running a c program to get the output

I need to type "exit" after I try to run my c program from command line. After the .exe, when I hit return key, I need to type exit to get the output.
Structure of programs :
#include<stdio.h>
int main(){
int a, r1, r2, r5, r10, r50, r100;
printf("Enter amount :");
scanf(" %d \n", &a);
r100 = a / 100;
a = a - (r100*100);
r50 = a / 50;
a = a - (r50*50);
r10 = a / 10;
a = a - (r10*10);
r5 = a / 5;
a = a - (r5*5);
r2 = a / 2;
a = a - (r2*2);
r1 = a;
printf("Rs100 denominations : %d", r100);
printf("\nRs50 denominations : %d", r50);
printf("\nRs10 denominations : %d", r10);
printf("\nRs5 denominations : %d", r5);
printf("\nRs2 denominations : %d", r2);
printf("\nRs1 denominations : %d", r1);
return 0;
}
Windows8.1, 64-bit..
compiling command >> gcc ykc1ij.c -o ykc1ij.exe ..
running >> ykc1ij.exe
As I commented, you'll better end every printf format string with \n. Read printf(3), scanf(3), fflush(3), perror(3) (and more generally, take the habit of reading the documentation of every function that you are using). You should test the result of scanf (it returns the number of successfully scanned items, or -1 on error), so:
printf("Enter amount :\n");
if (scanf(" %d \n", &a)<1)
{ perror("scanf failure"); exit(EXIT_FAILURE); };
You'll need to #include <stdlib.h> for exit(3).
Otherwise I suggest to initialize every variable (it is a good habit to have, since it makes your program runs more reproducible; a good optimizing compiler would remove the useless initializations):
int a=0, r1=0, r2=0;
BTW, I dislike the variable names you are using. They are not very meaningful to a human reader.
At last, compile with all warnings and debug info (e.g. with gcc -Wall -g), improve your code till you get no warnings, and learn how to use the debugger (e.g. gdb)

Informative "if" statement in "for" loop

Normally when I have a big for loop I put messages to inform me in which part of the process my program is, for example:
for(i = 0; i < large_n; i++) {
if( i % (large_n)/1000 == 0) {
printf("We are at %ld \n", i);
}
// Do some other stuff
}
I was wondering if this hurts too much the performance (a priori) and if it is the case if there is a smarter alternative.Thanks in advance.
Maybe you can split the large loop in order to check the condition sometimes only, but I don't know if this will really save time, that depends more on your "other stuff".
int T = ...; // times to check the condition, make sure large_n % T == 0
for(int t = 0; t < T; ++t)
{
for(int i = large_n/T * t; i < large_n/T * (t+1); ++i)
{
// other stuff
}
printf("We are at %ld \n", large_n/T * (t+1));
}
Regardless of what is in your loop, I wouldn't be leaving statements like printf in unless it's essential to the application/user, nor would I use what are effectively redundant if statements, for the same reason.
Both of these are examples of trace level debugging. They're totally valid and in some cases very useful, but generally not ultimately so in the end application. In this respect, a usual thing to do is to only include them in the build when you actually want to use the information they provide. In this case, you might do something like this:
#define DEBUG
for(i = 0; i < large_n; i++)
{
#ifdef DEBUG
if( i % (large_n)/1000 == 0)
{
printf("We are at %ld \n", i);
}
#endif
}
Regarding the performance cost of including these debug outputs all the time, it will totally depend on the system you're running, the efficiency of whatever "printing" statement you're using to output the data, the check/s you're performing and, of course, how often you're trying to perform output.
Your mod test probably doesn't hurt performance but if you want a very quick test and you're prepared for multiples of two then consider a mathematical and test:
if ( ( i & 0xFF ) == 0 ) {
/* this gets printed every 256 iterations */
...
}
or
if ( ( i & 0xFFFF ) == 0 ) {
/* this gets printed every 65536 iterations */
...
}
By placing a print statement inside of the for loop, you are sacrificing some performance.
Because the program needs to do a system call to write output to the screen every time the message is printed, it takes CPU time away from the program itself.
You can see the difference in performance between these two loops:
int i;
printf("Start Loop A\n");
for(i = 0; i < 100000; i++) {
printf("%d ", i);
}
printf("Done with Loop A\n");
printf("Start Loop B\n");
for(i = 0; i < 100000; i++) {
// Do Nothing
}
printf("Done with Loop B\n");
I would include timing code, but I am in the middle of work and can update it later over lunch.
If the difference isn't noticeable, you can increase 100000 to a larger number (although too large a number would cause the first loop to take WAY too long to complete).
Whoops, forgot to finish my answer.
To cut down on the number of system calls your program needs to make, you could check a condition first, and only print if that condition is true.
For example, if you were counting up as in my example code, you could only print out every 100th number by using %:
int i;
for(i = 0; i < 100000; i++) {
if(i%100 == 0)
printf("%d", i);
}
That will reduce the number of syscalls from ~100000 to ~1000, which in turn would increase the performance of the loop.
The problem is IO operation printf takes a much time than processor calculates. you can reduce the time if you can add them all and print finally.
Notation:
Tp = total time spent executing the progress statements.
Tn = total time spent doing the other normal stuff.
>> = Much greater than
If performance is your main criteria, you want Tn >> Tp. This strongly suggests that the code should be profiled so that you can pick appropriate values. The routine 'printf()' is considered a slow routine (much slower than %) and is a blocking routine (that is, the thread that calls it may pend waiting for a resource used by it).
Personally, I like to abstract away the progress indicator. It can be a logging mechanism,
a printf, a progress box, .... Heck, it may be updating a structure that is read by another thread/task/process.
id = progressRegister (<some predefined type of progress update mechanism>);
for(i = 0; i < large_n; i++) {
progressUpdate (id, <string>, i, large_n);
// Do some other stuff
}
progressUnregister(id);
Yes, there is some overhead in calling the routine 'progressUpdate()' on each iteration, but again, as long as Tn >> Tp, it usually is not that important.
Hope this helps.

Resources