I am very new to programming in C, and can't seem to locate the cause of the segmentation error that I have been getting. The program I wrote is as follows:
# include <stdio.h>
# include <stdlib.h>
int recursive(int x){
if(x=0)
{
return 2;
}
else
{
return 3*(x-1)+recursive(x-1)+1;
}
}
int main(int argc, char *argv[])
{
int N = atoi(argv[1]);
return recursive(N);
}
I would appreciate any help.
Thanks a lot
if(x=0){...}
it's wrong
It should be
if(x==0){...}
Note:
if (x = 0)
is the same as:
x = 0; if (x)
This:
if(x=0){
is not a (pure) test, it's an assignment. It works in the if since it also has a value (zero), but it's always false so that branch is never taken, i.e. the recursion never stops.
You should enable all compiler warnings, this is very commonly caught by compilers.
Change if(x = 0) to if(0 == x)
It is a good rule of hand to write 0 == x instead of x == 0 because in case of a typo like = instead of == the compiler will give an error.
The segfault error is from the use of argv[1]. Make sure you call your function with an argument, as follow:
$ ./a.out 6
with a.out the name of your program, and 6 the number you want to apply the function on.
The following line will create a segfault :
$ ./a.out
because the first argument isn't set.
Plus, watch out on the second line : use == instead of =
Related
I'm pretty new to coding and especially to C, so I decided to take the CS50 course as an introduction to the language. I just finished watching the first lecture on C and, as a means to test my knowledge on the subject, I attempted to write a short little program. Also I am using the course's library for the get_int() function.
The goal is to test the user's input and check if it's less or equal to ten. If it matches the parameters, the program should print the "Success!" message and exit; otherwise, it should ask for input again. If the input value is over 10, the program responds just as expected, but if you input a value of 10 or less, it ends up asking you for input one more time before actually exiting. I think it's probably something with the "for" loop, but I just can't figure it out.
My code:
#include <stdio.h>
#include <cs50.h>
#include <stdlib.h>
int check_for_value();
int main()
{
for(check_for_value(); check_for_value() != 1; check_for_value())
{
printf("Failed!\n");
}
exit(0);
}
int check_for_value()
{
int i = get_int("Your value: \n");
if(i <= 10)
{
printf("Success!\n");
return 1;
}
else
{
printf("Try again!\n");
return 0;
}
}
That isn't doing exactly what you think it is. In your for loop, each time you write check_for_value(), it is going to call that function. So it will call it the first time and the return value will not matter. It will call it again for the middle statement and then the value will matter because you are comparing the output to not equal to 1. And then again it will call the function in the third statement, where again it won't matter. Usually for something like this, you would use a while loop instead. An example below:
int ret = check_for_value();
while(ret != 1) {
printf("Failed\n");
ret = check_for_value();
}
printf("Success\n");
Technically a for loop can work too as the following:
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
The for loop can look very simply
for ( ; !check_for_value(); )
{
printf("Failed!\n");
}
In such a case it is better to use the while loop
while ( !check_for_value() )
{
printf("Failed!\n");
}
As for your for loop
for(check_for_value(); check_for_value() != 1; check_for_value())
^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^
then the underlined calls of the function are not tested.
Also bear in mind that such a definition of a for loop
for(int ret = check_for_value(); ret != 1; ret = check_for_value()) {
printf("Failed\n");
}
is a very bad style of programming. There is redundant records of the function calls. The intermediate variable ret is not used in the body of the loop. So its declaration is also redundant. Never use such a style of programming.
Pay attention to that according to the C Standard the function main without parameters shall be declared like
int main( void )
and the statement
exit( 0 );
is redundant.
I am using this library for libgps and having a few issues with it getting it to run properly.
The error from my debugger after it says segfault is:
Cannot find bounds of current function
The line of code throwing this is located in this file, on line 132.
uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16);
I don't know the context of this at all, and I dont know why it would / wouldn't throw a segfault.
My code:
#include <stdio.h>
#include <stdlib.h>
#include <gps.h>
#include <math.h>
/*
*
*/
int main(int argc, char** argv) {
// Open
gps_init();
gps_on();
loc_t data;
gps_location(&data);
printf("%lf %lf\n", data.latitude, data.longitude);
return (EXIT_SUCCESS);
}
The function gps_location() takes you into gps.c and from there it runs into serial.c, once it runs:
void serial_readln(char *buffer, int len)
{
char c;
char *b = buffer;
int rx_length = -1;
while(1) {
rx_length = read(uart0_filestream, (void*)(&c), 1);
if (rx_length <= 0) {
//wait for messages
sleep(1);
} else {
if (c == '\n') {
*b++ = '\0';
break;
}
*b++ = c;
}
}
}
On the break it returns to gps.c goes into:
switch (nmea_get_message_type(buffer)) {
which takes it into nmea.c for nmea_get_message_type above.
It then runs the line:
if ((checksum = nmea_valid_checksum(message)) != _EMPTY)
taking it down to: uint8_t checksum= (uint8_t)strtol(strchr(message, '*')+1, NULL, 16); which is where the error is.
What is causing this?
Edit:
uint8_t is defined as: typedef unsigned char uint8_t;
Segmentation fault is not a "thrown exception" per se, it is a hardware-issued problem ("you said go there, but I don't see anything named 'there'").
As for your problem: what happens when strchr() does not find the specified character? I suggest you try it and find out.
The code you are working with is horrible and has no error checking anywhere. So it may go haywire for any unexpected input. This could be a potential security vulnerability too.
To fix this particular instance, change the code to:
if ( !message )
return NMEA_CHECKSUM_ERR; // possibly `exit` or something, this shouldn't happen
char *star = strchr(message, '*');
if ( !star )
return NMEA_CHECKSUM_ERR;
uint8_t checksum = strtol(star, NULL, 16);
The nmea_parse_gpgga and nmea_parse_gprmc also have multiple instances of a similar problem.
These functions might be acceptable if there was a parser or a regexp check that sanitizes the input before calling these functions. However, based on your question (I didn't check the codebase), it seems data is passed directly from read which is inexcusable.
The segfaulting function was not designed to handle an empty message or in fact any message not matching the expected form.
Another disastrous blunder is that the serial_readln function never checks that it does not write beyond len.
I have tried so many things. Running from command line, running from cmd, running with /K, putting system("pause"); getchar(); getch(); before return 0 and I simply can't get it to run. I'm writing in Notepad++, compiling in Cygwin and the window appears blank for the split second it appears (according to my screenshot, it could have been taken too early). Basically I've tried anything I could Google myself to. So I figured it must be something wrong with my code that the debugger doesn't show.
#include <stdio.h>
int main()
{
float lt1, lt2, dmg, x;
lt1=10;
lt2=30;
while(lt2>dmg)
{
while(x>0 || lt2>dmg)
{
dmg=dmg+x*lt1;
x--;
return (dmg);
}
x=x+0.01;
return (x);
}
printf("Horde factor is: %f", x);
return 0;
}
I would appreciate any help I can get, and I hope you will bear over with my inexperience.
You have undefined behavior in your code.
When you declare a local variable without assigning anything to it, its value is indeterminate. Usage of this variable will be undefined behavior until you assign a value to it.
In this case it's the dmg and x variables that causes this problem.
Its because of these statement :
return (dmg); //this ends the code execution .. because you have returned something from main()
x=x+0.01;
return (x); // even this one is wrong
you are exiting the code there and never getting to the printf ..
there should only be one return in main() .. and at the end.
More problems with your code:
you don't initialise dmg and x , but you use them as parameters for while loop
float lt1, lt2, dmg, x; // dmg,x uninitialized
In the outer while loop .. its an infinite loop as you don't do anything to the parameters of that loop to get out of it.
Like I said above .. there should be only 1 return in main()
Maybe instead of returning you should look into break; ( i don't know if thats what you want or not as I don't understand your code )
I've written a function that determines whether or not to assign default values (it assigns default values if the flag is not present, and it assigns values the user passes if the flag is present). And I'm trying to test my function with a string to see if it did give me the right numbers. I keep getting "Segmentation Fault" when I try to run the tests, it compiles, but the tests just don't work. :(
Here's my header file:
#ifndef COMMANDLINE_H
#define COMMANDLINE_H
#include "data.h"
#include <stdio.h>
struct point eye;
/* The variable listed above is a global variable */
void eye_flag(int arg_list, char *array[]);
#endif
Here's my implementation file:
#include <stdio.h>
#include "commandline.h"
#include "data.h"
#include "string.h"
/* Used global variables for struct point eye */
void eye_flag(int arg_list, char *array[])
{
eye.x = 0.0;
eye.y = 0.0;
eye.z = -14.0;
/* The values listed above for struct point eye are the default values. */
for (int i = 0; i <= arg_list; i++)
{
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
}
And here are my test cases:
#include "commandline.h"
#include "checkit.h"
#include <stdio.h>
void eye_tests(void)
{
char *arg_eye[6] = {"a.out", "sphere.in.txt", "-eye", "2.4", "3.5", "6.7"};
eye_flag(6, arg_eye);
checkit_double(eye.x, 2.4);
checkit_double(eye.y, 3.5);
checkit_double(eye.z, 6.7);
char *arg_eye2[2] = {"a.out", "sphere.in.txt"};
eye_flag(2, arg_eye2);
checkit_double(eye.x, 0.0);
checkit_double(eye.y, 0.0);
checkit_double(eye.z, -14.0);
}
int main()
{
eye_tests();
return 0;
}
The absolute easiest way to solve this one is run it in a debugger. You probably won't even need to learn how to step through your code or anything - just fire up, run, and read the line.
If you are on a *nix system:
Compile your code with -g flag.
Load as, e.g. gdb a.out.
Run now that it's loaded - (gdb) run.
Do whatever you need to reproduce the segfault.
bt or where should give you a stack trace - and an exact line that is causing your problem.
I'm sure enough you can solve it from there to post this as an answer; but if not, knowing the exact line will make it very much easier to research and solve.
The errors are here:
for (int i = 0; i <= arg_list; i++)
{ ///^^
if (strcmp(array[i], "-eye") == 0)
{
sscanf(array[i+1], "%lf", &eye.x);
//^^^
sscanf(array[i+2], "%lf", &eye.y);
sscanf(array[i+3], "%lf", &eye.z);
}
}
i <= arg_list is wrong since you pass in 6, array index starts from 0, the max value is 5
i+1, i+2,i+3 will give you out of bounds index when you iterate from 0 to 5.
Your loop condition is wrong. It should be i < arg_list.
Think about what happens when i == arg_list.
I'm trying to learn C by writing a simple parser / compiler. So far its been a very enlightening experience, however coming from a strong background in C# I'm having some problems adjusting - in particular to the lack of exceptions.
Now I've read Cleaner, more elegant, and harder to recognize and I agree with every word in that article; In my C# code I avoid throwing exceptions whenever possible, however now that I'm faced with a world where I can't throw exceptions my error handling is completely swamping the otherwise clean and easy-to-read logic of my code.
At the moment I'm writing code which needs to fail fast if there is a problem, and it also potentially deeply nested - I've settled on a error handling pattern whereby "Get" functions return NULL on an error, and other functions return -1 on failure. In both cases the function that fails calls NS_SetError() and so all the calling function needs to do is to clean up and immediately return on a failure.
My issue is that the number of if (Action() < 0) return -1; statements that I have is doing my head in - it's very repetitive and completely obscures the underlying logic. I've ended up creating myself a simple macro to try and improve the situation, for example:
#define NOT_ERROR(X) if ((X) < 0) return -1
int NS_Expression(void)
{
NOT_ERROR(NS_Term());
NOT_ERROR(Emit("MOVE D0, D1\n"));
if (strcmp(current->str, "+") == 0)
{
NOT_ERROR(NS_Add());
}
else if (strcmp(current->str, "-") == 0)
{
NOT_ERROR(NS_Subtract());
}
else
{
NS_SetError("Expected: operator");
return -1;
}
return 0;
}
Each of the functions NS_Term, NS_Add and NS_Subtract do a NS_SetError() and return -1 in the case of an error - its better, but it still feels like I'm abusing macros and doesn't allow for any cleanup (some functions, in particular Get functions that return a pointer, are more complex and require clean-up code to be run).
Overall it just feels like I'm missing something - despite the fact that error handling in this way is supposedly easier to recognize, In many of my functions I'm really struggling to identify whether or not errors are being handled correctly:
Some functions return NULL on an error
Some functions return < 0 on an error
Some functions never produce an error
My functions do a NS_SetError(), but many other functions don't.
Is there a better way that I can structure my functions, or does everyone else also have this problem?
Also is having Get functions (that return a pointer to an object) return NULL on an error a good idea, or is it just confusing my error handling?
It's a bigger problem when you have to repeat the same finalizing code before each return from an error. In such cases it is widely accepted to use goto:
int func ()
{
if (a() < 0) {
goto failure_a;
}
if (b() < 0) {
goto failure_b;
}
if (c() < 0) {
goto failure_c;
}
return SUCCESS;
failure_c:
undo_b();
failure_b:
undo_a();
failure_a:
return FAILURE;
}
You can even create your own macros around this to save you some typing, something like this (I haven't tested this though):
#define CALL(funcname, ...) \
if (funcname(__VA_ARGS__) < 0) { \
goto failure_ ## funcname; \
}
Overall, it is a much cleaner and less redundant approach than the trivial handling:
int func ()
{
if (a() < 0) {
return FAILURE;
}
if (b() < 0) {
undo_a();
return FAILURE;
}
if (c() < 0) {
undo_b();
undo_a();
return FAILURE;
}
return SUCCESS;
}
As an additional hint, I often use chaining to reduce the number of if's in my code:
if (a() < 0 || b() < 0 || c() < 0) {
return FAILURE;
}
Since || is a short-circuit operator, the above would substitute three separate if's. Consider using chaining in a return statement as well:
return (a() < 0 || b() < 0 || c() < 0) ? FAILURE : SUCCESS;
One technique for cleanup is to use an while loop that will never actually iterate. It gives you goto without using goto.
#define NOT_ERROR(x) if ((x) < 0) break;
#define NOT_NULL(x) if ((x) == NULL) break;
// Initialise things that may need to be cleaned up here.
char* somePtr = NULL;
do
{
NOT_NULL(somePtr = malloc(1024));
NOT_ERROR(something(somePtr));
NOT_ERROR(somethingElse(somePtr));
// etc
// if you get here everything's ok.
return somePtr;
}
while (0);
// Something went wrong so clean-up.
free(somePtr);
return NULL;
You lose a level of indentation though.
Edit: I'd like to add that I've nothing against goto, it's just that for the use-case of the questioner he doesn't really need it. There are cases where using goto beats the pants off any other method, but this isn't one of them.
You're probably not going to like to hear this, but the C way to do exceptions is via the goto statement. This is one of the reasons it is in the language.
The other reason is that goto is the natural expression of the implementation of a state machine. What common programming task is best represented by a state machine? A lexical analyzer. Look at the output from lex sometime. Gotos.
So it sounds to me like now is the time for you to get chummy with that parriah of language syntax elements, the goto.
Besides goto, standard C has another construct to handle exceptional flow control setjmp/longjmp. It has the advantage that you can break out of multiply nested control statements more easily than with break as was proposed by someone, and in addition to what goto provides has a status indication that can encode the reason for what went wrong.
Another issue is just the syntax of your construct. It is not a good idea to use a control statement that can inadvertibly be added to. In your case
if (bla) NOT_ERROR(X);
else printf("wow!\n");
would go fundamentally wrong. I'd use something like
#define NOT_ERROR(X) \
if ((X) >= 0) { (void)0; } \
else return -1
instead.
THis must be thought on at least two levels: how your functions interact, and what you do when it breaks.
Most large C frameworks I see always return a status and "return" values by reference (this is the case of the WinAPI and of many C Mac OS APIs). You want to return a bool?
StatusCode FooBar(int a, int b, int c, bool* output);
You want to return a pointer?
StatusCode FooBar(int a, int b, int c, char** output);
Well, you get the idea.
On the calling function's side, the pattern I see the most often is to use a goto statement that points to a cleanup label:
if (statusCode < 0) goto error;
/* snip */
return everythingWentWell;
error:
cleanupResources();
return somethingWentWrong;
What about this?
int NS_Expression(void)
{
int ok = 1;
ok = ok && NS_Term();
ok = ok && Emit("MOVE D0, D1\n");
ok = ok && NS_AddSub();
return ok
}
The short answer is: let your functions return an error code that cannot possibly be a valid value - and always check the return value. For functions returning pointers, this is NULL. For functions returning a non-negative int, it's a negative value, commonly -1, and so on...
If every possible return value is also a valid value, use call-by-reference:
int my_atoi(const char *str, int *val)
{
// convert str to int
// store the result in *val
// return 0 on success, -1 (or any other value except 0) otherwise
}
Checking the return value of every function might seem tedious, but that's the way errors are handled in C. Consider the function nc_dial(). All it does is checking its arguments for validity and making a network connection by calling getaddrinfo(), socket(), setsockopt(), bind()/listen() or connect(), finally freeing unused resources and updating metadata. This could be done in approximately 15 lines. However, the function has nearly 100 lines due to error checking. But that's the way it is in C. Once you get used to it, you can easily mask the error checking in your head.
Furthermore, there's nothing wrong with multiple if (Action() == 0) return -1;. To the contrary: it is usually a sign of a cautious programmer. It's good to be cautious.
And as a final comment: don't use macros for anything but defining values if you can't justify their use while someone is pointing with a gun at your head. More specifically, never use control flow statements in macros: it confuses the shit out of the poor guy who has to maintain your code 5 years after you left the company. There's nothing wrong with if (foo) return -1;. It's simple, clean and obvious to the point that you can't do any better.
Once you drop your tendency to hide control flow in macros, there's really no reason to feel like you're missing something.
A goto statement is the easiest and potentially cleanest way to implement exception style processing. Using a macro makes it easier to read if you include the comparison logic inside the macro args. If you organize the routines to perform normal (i.e. non-error) work and only use the goto on exceptions, it is fairly clean for reading. For example:
/* Exception macro */
#define TRY_EXIT(Cmd) { if (!(Cmd)) {goto EXIT;} }
/* My memory allocator */
char * MyAlloc(int bytes)
{
char * pMem = NULL;
/* Must have a size */
TRY_EXIT( bytes > 0 );
/* Allocation must succeed */
pMem = (char *)malloc(bytes);
TRY_EXIT( pMem != NULL );
/* Initialize memory */
TRY_EXIT( initializeMem(pMem, bytes) != -1 );
/* Success */
return (pMem);
EXIT:
/* Exception: Cleanup and fail */
if (pMem != NULL)
free(pMem);
return (NULL);
}
It never occurred to me to use goto or do { } while(0) for error handling in this way - its pretty neat, however after thinking about it I realised that in many cases I can do the same thing by splitting the function out into two:
int Foo(void)
{
// Initialise things that may need to be cleaned up here.
char* somePtr = malloc(1024);
if (somePtr = NULL)
{
return NULL;
}
if (FooInner(somePtr) < 0)
{
// Something went wrong so clean-up.
free(somePtr);
return NULL;
}
return somePtr;
}
int FooInner(char* somePtr)
{
if (something(somePtr) < 0) return -1;
if (somethingElse(somePtr) < 0) return -1;
// etc
// if you get here everything's ok.
return 0;
}
This does now mean that you get an extra function, but my preference is for many short functions anyway.
After Philips advice I've also decided to avoid using control flow macros as well - its clear enough what is going on as long as you put them on one line.
At the very least Its reassuring to know that I'm not just missing something - everyone else has this problem too! :-)
Use setjmp.
http://en.wikipedia.org/wiki/Setjmp.h
http://aszt.inf.elte.hu/~gsd/halado_cpp/ch02s03.html
http://www.di.unipi.it/~nids/docs/longjump_try_trow_catch.html
#include <setjmp.h>
#include <stdio.h>
jmp_buf x;
void f()
{
longjmp(x,5); // throw 5;
}
int main()
{
// output of this program is 5.
int i = 0;
if ( (i = setjmp(x)) == 0 )// try{
{
f();
} // } --> end of try{
else // catch(i){
{
switch( i )
{
case 1:
case 2:
default: fprintf( stdout, "error code = %d\n", i); break;
}
} // } --> end of catch(i){
return 0;
}
#include <stdio.h>
#include <setjmp.h>
#define TRY do{ jmp_buf ex_buf__; if( !setjmp(ex_buf__) ){
#define CATCH } else {
#define ETRY } }while(0)
#define THROW longjmp(ex_buf__, 1)
int
main(int argc, char** argv)
{
TRY
{
printf("In Try Statement\n");
THROW;
printf("I do not appear\n");
}
CATCH
{
printf("Got Exception!\n");
}
ETRY;
return 0;
}