c++ - Definitive List of Common Reasons for Segmentation Faults -
note: have lot of segfault questions, largely same answers, i'm trying collapse them canonical question have undefined reference.
although have question covering what segmentation fault is, covers what, doesn't list many reasons. top answer says "there many reasons", , lists one, , of other answers don't list reasons.
all in all, believe need well-organized community wiki on topic, lists common causes (and some) segfaults. purpose aid in debugging, mentioned in answer's disclaimer.
i know segmentation fault is, can hard spot in code without knowing like. although there are, no doubt, far many list exhaustively, what common causes of segmentation faults in c , c++?
warning!
the following potential reasons segmentation fault. it virtually impossible list reasons. purpose of list diagnose existing segfault.
the relationship between segmentation faults , undefined behavior cannot stressed enough! of below situations can create segmentation fault technically undefined behavior. means can anything, not segfault -- once said on usenet, "it legal compiler make demons fly out of nose.". don't count on segfault happening whenever have undefined behavior. should learn undefined behaviors exist in c and/or c++, , avoid writing code has them!
more information on undefined behavior:
what segfault?
in short, segmentation fault caused when code attempts access memory doesn't have permission access. every program given piece of memory (ram) work with, , security reasons, allowed access memory in chunk.
for more thorough technical explanation segmentation fault is, see what segmentation fault?.
here common reasons segmentation fault error. again, these should used in diagnosing existing segfault. learn how avoid them, learn language's undefined behaviors.
this list no replacement doing own debugging work. (see section @ bottom of answer.) these things can for, debugging tools reliable way 0 in on problem.
accessing null or uninitialized pointer
if have pointer null (ptr=0) or uninitialized (it isn't set @ yet), attempting access or modify using pointer has undefined behavior.
int* ptr = 0; *ptr += 5; since failed allocation (such malloc or new) return null pointer, should check pointer not null before working it.
note reading values (without dereferencing) of uninitialized pointers (and variables in general) undefined behavior.
sometimes access of undefined pointer can quite subtle, such in trying interpret such pointer string in c print statement.
char* ptr; sprintf(id, "%s", ptr); see also:
- how detect if variable uninitialized/catch segfault in c
- concatenation of string , int results in seg fault c
accessing dangling pointer
if use malloc or new allocate memory, , later free or delete memory through pointer, pointer considered dangling pointer. dereferencing (as reading value - granted didn't assign new value such null) undefined behavior, , can result in segmentation fault.
something* ptr = new something(123, 456); delete ptr; std::cout << ptr->foo << std::endl; see also:
stack overflow
[no, not site you're on now, named for.] oversimplified, "stack" spike stick order paper on in diners. problem can occur when put many orders on spike, speak. in computer, variable not dynamically allocated , command has yet processed cpu, goes on stack.
one cause of might deep or infinite recursion, such when function calls no way stop. because stack has overflowed, order papers start "falling off" , taking other space not meant them. thus, can segmentation fault. cause might attempt initialize large array: it's single order, 1 large enough itself.
int stupidfunction(int n) { return stupidfunction(n); } another cause of stack overflow having many (non-dynamically allocated) variables @ once.
int stupidarray[600851475143]; one case of stack overflow in wild came simple omission of return statement in conditional intended prevent infinite recursion in function. moral of story, always ensure error checks work!
see also:
wild pointers
creating pointer random location in memory playing russian roulette code - miss , create pointer location don't have access rights to.
int n = 123; int* ptr = (&n + 0xdeadbeef); //this stupid, people. as general rule, don't create pointers literal memory locations. if work 1 time, next time might not. can't predict program's memory @ given execution.
see also:
attempting read past end of array
an array contiguous region of memory, each successive element located @ next address in memory. however, arrays don't have innate sense of how large are, or last element is. thus, easy blow past end of array , never know it, if you're using pointer arithmetic.
if read past end of array, may wind going memory uninitialized or belongs else. technically undefined behavior. segfault 1 of many potential undefined behaviors. [frankly, if segfault here, you're lucky. others harder diagnose.]
// ub, code total crapshoot. int arr[3] {5, 151, 478}; int = 0; while(arr[i] != 16) { std::cout << arr[i] << std::endl; i++; } or seen 1 using for <= instead of < (reads 1 byte much):
char arr[10]; (int = 0; i<=10; i++) { std::cout << arr[i] << std::endl; } or unlucky typo compiles fine (seen here) , allocates 1 element initialized dim instead of dim elements.
int* my_array = new int(dim); additionally should noted not allowed create (not mention dereferencing) pointer points outside array (you can create such pointer if points element within array, or 1 past end). otherwise, triggering undefined behaviour.
see also:
forgetting nul terminator on c string.
c strings are, themselves, arrays additional behaviors. must null terminated, meaning have \0 @ end, reliably used strings. done automatically in cases, , not in others.
if forgotten, functions handle c strings never know when stop, , can same problems reading past end of array.
char str[3] = {'f', 'o', 'o'}; int = 0; while(str[i] != '\0') { std::cout << str[i] << std::endl; i++; } with c-strings, hit-and-miss whether \0 make difference. should assume avoid undefined behavior.
attempting modify string literal
if assign string literal char*, cannot modified. example...
char* foo = "hello, world!" foo[7] = 'w'; ...triggers undefined behavior, , segmentation fault 1 possible outcome.
see also:
mismatching allocation , deallocation methods
you must use malloc , free together, new , delete together, , new[] , delete[] together. if mix 'em up, can segfaults , other weird behavior.
see also:
errors in toolchain.
a bug in machine code backend of compiler quite capable of turning valid code executable segfaults. bug in linker can too.
particularly scary in not ub invoked own code.
that said, you should assume problem until proven otherwise.
other causes
the possible causes of segmentation faults numerous number of undefined behaviors, , there far many standard documentation list.
a few less common causes check:
debugging
debugging tools instrumental in diagnosing causes of segfault. compile program debugging flag (-g), , run debugger find segfault occurring.
recent compilers support building -fsanitize=address, typically results in program run 2x slower can detect address errors more accurately. however, other errors (such reading uninitialized memory or leaking non-memory resources such file descriptors) not supported method, , impossible use many debugging tools , asan @ same time.
some memory debuggers
- gdb | mac, linux
- valgrind (memcheck)| linux
- dr. memory | windows
additionally recommended use static analysis tools detect undefined behaviour - again, tool merely find undefined behaviour, , don't guarantee find occurrences of undefined behaviour.
if unlucky however, using debugger (or, more rarely, recompiling debug information) may influence program's code , memory sufficiently segfault no longer occurs, phenomenon known heisenbug.
Comments
Post a Comment