C++ 2D Array Allocating Memory to Avoid Segmentation Fault
C++ gives you control of where you want to allocate memory. In your case, what you have found is that you allocated an array-of-array-of-int on the stack which exceeds the stack size. At some point, you access one of these elements which lies outside the bounds of the stack and also the program, which causes an access violation called a segmentation fault.
Since you mentioned being new to C++, it would help to understand these 3 areas of memory and how you would use each for your case:
Stack memory - space for temporary variables to automatically use without having to explicitly request. You will see undefined behavior if you exceed the stack size.
int main() {
int arr[100000][100000];
}
Heap memory - space for dynamically allocating space whenever explicitly requested using the operator "new". An "std::bad_alloc" exception will be thrown if the requested memory size exceeds what is available.
int main() {
int **arr = new int *[100000];
for (std::size_t i = 0; i < 100000; ++i) {
arr[i] = new int[100000];
}
}
Static memory - space allocated for static objects before main runs. You will get a compiler error if the array dimensions are too large.
int arr[100000][100000];
int main() {
...
}
Seg fault in case of large 2D array
Probably you are running out of stack space.
Can you not allocate the array dynamically on heap using malloc
?
You may want to have a look at this answer if you do not know how to do that.
Segmentation fault when trying to print out/load a 2d array
First, you have a memory leak. To avoid the leak and to have better bounds checking you should consider using std::vector<std::vector<int>>
rather than int**
.
Your crash is due to the second failure. When the second load
fails, it returns 0, i.e. nullptr
(it is recommended to use nullptr
rather than 0 in this case). Later, show
tries to dereference this nullptr
-- causing segmentation fault.
If you insist on using raw pointers, rather than vectors or, the second best, unique_ptr then you must make sure the allocations are cleaned up on failure of load
, and between consecutive successful calls to load
(and at the end).
Edit
The second call is corrupted because of the integer 355. Also, your column's and rows seem to be transposed (rows are treated as columns and columns treated as rows).
Why does declaring a 2D array of sufficient size cause a segfault on Linux but not macOS?
Although ISO C++ does not support variable-length arrays, you seem to be using a compiler which supports them as an extension.
In the line
int Matrix2D[n][n];
n
can have a value up to 2000
. This means that the 2D array can have 2000*2000
elements, which equals 4 million. Every element has a size of sizeof(int)
, which is 4
bytes on linux. This means that you are allocating a total of 16 Megabytes on the stack. This is exceeding the limit of the stack, causing a stack overflow.
The reason why it is not crashing on MacOS could be that the stack is configured for a higher maximum limit, or it could be that your program is not crashing because variable-length arrays are implemented differently, so that the program is not touching the 2D array, or maybe it is touching the 2D array, but only in such a way that it doesn't cause a crash. These are implementation-details of the compiler.
The amount of memory actually installed on the computer is not relevant. What counts is the maximum stack limit configured in the operating system.
If you want to use larger amounts of memory than would be permitted on the stack, you should use the heap instead. In that case, you should allocate the memory instead with std::make_unique
, operator new
or std::malloc
. You can also use most STL containers such as std::vector
, which will automatically store its contents on the heap, even if you create the actual container on the stack. However, beware that some STL containers will not, such as std::array
.
C: 2-Dimensional String Array Segmentation Fault
Replace all ocurrences of array[c][r]
with array[r][c]
The first dimension is the row.
Next time you can check this using a debugger:
Program received signal SIGSEGV, Segmentation fault.
0x00000000004007ea in main () at demo.c:37
37 array[c][r] = str[i];
Related Topics
How to Use Threads to Speed Up File Reading
How to Pack a Visual Studio C++ Project for Release
What Is Use of the Ref-Qualifier 'Const &&'
How to Safely Average Two Unsigned Ints in C++
Error for Hash Function of Pair of Ints
Where in Memory Is Vtable Stored
How to Add Element by Element of Two Stl Vectors
How to Get Hash Code of a String in C++
Does Auto Deduce the Type at Compile Time or Runtime in C++ 11
Why Should I Initialize Member Variables in the Order They'Re Declared In
How to Call an External Program with Parameters
How to Check If a Process Has the Administrative Rights
How to Write a Stateful Allocator in C++11, Given Requirements on Copy Construction
Opensouce C/C++ Math Expression Parser Library
Default Move Constructor/Assignment and Deleted Copy Constructor/Assignment