General Causes
◀ What Segmentation Fault Really Is▶ How to Avoid Segmentation Fault Amazon
From my experience the general causes of a segmentation fault are the following:
- Out of bounds access of an array
- Deletion or freeing of memory that has not been allocated a certain way
- Access of data members of a null pointer
Let’s look into these causes one by one.
The First Cause
The
first general cause is out of bounds access of an array. As surprising as it may sound, an out-of-bounds access of an array element doesn’t always generate a segmentation fault.
The following is a sample program that demonstrates the effects of out-of-bounds element accesses of an integer array and of a
vector.
#include<iostream>
#include<vector>
using namespace std;
int main(int argc, char** argv){
int i;
int input;
vector<int> v;
int a[100];
int version;
if(argc!=2){
cout<< "usage: exe <version>\n";
cout<<"where version is 0 for array and 1 for vector implementation \n";
exit(1);
}
version=atoi(argv[1]);
if(version==0) {
for(i=0;i<100;i++)
v.push_back(i);
cout << "There are a total of 100 elements in the vector.\n";
}
else {
for(i=0;i<100;i++)
a[i]=i;
cout << "There are a total of 100 elements in the array.\n";
}
cout<<"Please input a number: ";
cin>>input;
if(version==0){
cout<<"The "<<input<<"'th item in the vector is: ";
cout<<v[input];
}
else{
cout<<"The "<<input<<"'th item in the array is: ";
cout<<a[input];
}
return 0;
}
Now try inputting 100, 200, or even 1000 and see what happens. Out-of-bounds array accesses may or may not result in a segmentation fault!
As mentioned earlier, a segmentation fault occurs due to the segment violation in the memory address space. As long as the address does not reference an illegitimate segment (usually the one used by another process), compiler does not raise a segmentation fault but prints out whatever resides at that address which mostly likely is garbage.
Slightly out-of-bounds addresses may well contain data not referenced by any process, so such array element accesses may not result in a segmentation fault, but accessing addresses significantly distant from the allocated space most likely results in a segmentation fault.
The Second Cause
The
second general cause is incorrect use of standard library functions that allocate and deallocate memory. For example, here is an example of incorrect use of delete:
#include<iostream>
using namespace std;
int main(){
int a=5;
int *b=&a;
delete b;
return 0;
}
If you compile and run it it is likely to give you a segmentation fault because delete is used with a pointer that did not use new earlier to allocate memory. You cannot apply delete to free memory allocated without using new.
By the way, you do not have to use the same pointer you used with new; you just have to use the same address, as the following example illustrates:
int *a = new int; // allocate memory via new
int *b = a; // b points to the address a points to
delete b; // perfectly legal
The Third Cause
The
third general cause is trying to access data associated with a
null pointer.
Suppose you have a pointer pointing to a struct which has a couple of data items. To access those data items, the pointer needs to point to a defined struct object; it cannot be a null pointer or a pointer pointing to an undefined struct reference. In these situations, accesses to data items of the struct most likely result in a segmentation fault.
It is possible, though rarely, that after you use new to allocate memory and use that memory you get a segmentation fault. This is most likely due to memory shortage. If this is the case, new returns the value 0, or NULL. So you can check what is returned by new before you start manipulating that object.
Now that we discussed common sources of a segmentation fault let’s discuss how to avoid it!
◀ What Segmentation Fault Really Is▶ How to Avoid Segmentation Fault