25

I am writing C code, in which I am analyzing some data. I have set the program to handle only 100 data inputs. When it has more than 100 inputs, it is giving a segmentation fault. I want to create a way so that when the number of inputs is above 100 the user will be warned and the program will terminate. I know how to do it from the main function by simply return 0, however I am multiple function calls away from main and it is difficult to do that even a return 0 in this function will keep it looping.

Is there any immediate way to terminate the entire program without being in main?

mgthomas99
  • 5,402
  • 3
  • 19
  • 21
Syntax_Error
  • 5,964
  • 15
  • 53
  • 73
  • 11
    You can use `exit(int)` from ``, but I think you might want to look into why your program can't handle more than 100 data points. Unless it's by design or you don't want them to do it anyway. – wkl Nov 01 '11 at 22:16
  • birryree is correct. Although it *is* possible to suddenly exit from anywhere in the program it is extremely bad practice (especially if you haven't cleaned up the memory you have in pointers and other objects). You're better off gracefully handling the scenario where they have >100 data inputs and quitting with an error code once its all cleaned up. – Grambot Nov 01 '11 at 22:17
  • That `exit` tag looks so foreshadowing now... – hugomg Nov 01 '11 at 22:17
  • 3
    @TheCapn are you aware that upon exiting a program, all memory (both heap and stack) are cleaned up automatically? I haven't seen a truly persistent memory leak since Windows 98. – Chris Eberle Nov 01 '11 at 22:23
  • You should not return 0 from main if your program fails. If you return zero, you are telling the OS you were successful. It is better to return EXIT_FAILURE when you fail, and EXIT_SUCCESS (0) only when the program succeeds. – William Pursell Nov 01 '11 at 22:47
  • @ChrisEberle And that's the rub - we don't know what OS he is using - it might actually be Windows 98. Embedded devices sometimes still use MS DOS... – Jerry Jeremiah Apr 08 '20 at 03:10

4 Answers4

42

The standard function exit is what you are looking for:

Terminates the process normally, performing the regular cleanup for terminating processes.

First, all functions registered by calls to atexit are executed in the reverse order of their registration. Then, all streams are closed and the temporary files deleted, and finally the control is returned to the host environment.

The status argument is returned to the host environment.

It would be better though if you fixed the segfault error.

K-ballo
  • 80,396
  • 20
  • 159
  • 169
8

You need to include the standard lib and then you can call exit wherever you want:

#include <stdlib.h>
...
exit(status);

where status is an integer representing the exit code. For what concern status: for the convention 0 is success, other values indicates an error status.

Heisenbug
  • 38,762
  • 28
  • 132
  • 190
  • 2
    The standard provides the constants EXIT_SUCCESS and EXIT_FAILURE. There have been machines in which any even number was considered success, while odd values were failures. – William Pursell Nov 01 '11 at 22:44
2

A slightly better thing to do might be to catch the segmentation fault with a signal handler, and have the signal handler raise a SIGSTOP signal.

That way your program stops, but stays in memory. You can then attach to it with a debugger and see the program in all its glory frozen in place at the point the SEGFAULT happened.

That can be useful for finding problems in long running programs that you aren't running inside a development IDE.

bazza
  • 7,580
  • 15
  • 22
  • 1
    That is the right answer. Not just advising to fix the actual problem but with constructive advice on how to do it. Of course it is a POSIX only answer, but still... – Jerry Jeremiah Apr 08 '20 at 03:13
  • @JerryJeremiah It's a handy trick I've used in some system types, with the added benefit that if one can identify why the segfault was raised in the first place and that the fix is simply to edit a variable value (not always possible), one can resume the process afterwards! I've also used it as a way of doing other things like sending "suspend" messages to other processes (sometimes on other machines) before the sigstop is raised, to bring an entire infrastructure to a grinding halt. Also I'm a fan these days of signalfd - a really good thing Linux has nowadays – bazza Apr 08 '20 at 07:43
2

You can also fprintf(stderr, ....) and then call abort(); this can be helpful if you want to debug later your bug.

But I believe you should recode your program so that size limitations are only given by available resources: so if you run your program on a much bigger computer (whatever that means) it could process more than 100 inputs.

Basile Starynkevitch
  • 223,805
  • 18
  • 296
  • 547