I have the challenge to implement simplex-method (or simplex algorithm). Simplex-method is a popular algorithm for linear programming which is based on rebuilding matrices. My program should return an optimal solution. I have a C++ project in Clion. It works correctly when I run the program, but during the debug I get a SIGSEGV Signal (Segmentation Fault) in one of the methods. It happens when I try to allocate memory for the matrix. Here is the part of code:
double **newTable;
newTable = new double *[rows];
for (int i = 0; i < rows; ++i) {
for (int j = 0; j < cols; ++j) {
newTable[i] = new double [cols];
}
}
I free the memory at the end of the method using delete[], but it doesn’t work.
I’ve already tried to run the program in another IDE (CodeBlocks), but it works properly too, and I have no idea why it happens and where the problem occurs.
No need for this nested loop. You only need one loop to allocate memory for this jagged array:
int main() {
int rows = 5, cols = 10;
double **newTable;
newTable = new double *[rows];
for (int i = 0; i < rows; ++i)
newTable[i] = new double[cols];
for (int i = 0; i < rows; ++i)
delete newTable[i];
delete newTable;
}
The way your code is now it will leak memory, but that alone won't cause a segmentation fault. There might be a mistake with how you're freeing the memory, too.
Also, since this is C++, may I recommend using std::vector instead?
#include <vector>
int main() {
std::vector<std::vector<double>> newTable(5, std::vector<double>(10));
}
Related
The following code is throwing Segmentation fault (core dumped) error when I run it. The code is compiled with g++
struct SomeClass {
int *available;
int **need;
int **allocation;
}
SomeClass::SomeClass(int nR, int nT) {
available = new int[nR];
for (int i = 0; i < nR; i++) {
available[i] = 1;
}
*allocation = new int[nT];
*need = new int[nT];
for (int i = 0; i < nT; i++) {
allocation[i] = new int[nR];
need[i] = new int[nR];
for (int j = 0; j < nR; j++) {
allocation[i][j] = 0;
need[i][j] = 1; // should equal 1
}
}
}
Am I sure that this code is generating the error? YES! Because I commented it out and everything works fine.
I checked this question:
A segmentation fault error with 2D array
The answer says to set the stack size ulimit -s unlimited... But that didn't fix the problem.
Because your types are:
int **need;
int **allocation;
these lines:
*allocation = new int[nT]; // dereferencing uninitialized pointer
*need = new int[nT];
should be:
allocation = new int*[nT]; // proper allocation
need = new int*[nT];
Didn't you think you'd need elements of int* type for allocation[i] = new int[nR]; to work?
I strongly suggest (and strongly feel deja vu) to move away from an attempt to emulate 2-D arrays with pointers to pointers. It is hard to do this right. Pack all your values into single-dimensional array.
I'm using c++ and I want to use two dimensional dynamic array. I tried this:
#include<iostream.h>
using namespace std;
void main(){
int const w=2;
int size;
cout<<"enter number of vertex:\n";
cin>>size;
int a[size][w];
for(int i=0; i<size; i++)
for(int j=0; j<w; j++){
cin>>a[i][j];
}
}
but not worded.
and I tried this:
int *a = new a[size][w];
instead of
int a[size][w];
but not worked!
could you help me plz.
thanks a lot.
The correct approach here would be to encapsulate some of the standard containers, that will manage memory for you, inside a class that provides a good interface. The common approach there would be an overload of operator() taking two arguments that determine the row and column in the matrix.
That aside, what you are trying to create manually is an array of dynamic size of arrays of constant size 2. With the aid of typedef you can write that in a simple to understand manner:
const int w = 2;
typedef int array2int[w];
int size = some_dynamic_value();
array2int *p = new array2int[size];
Without the typedef, the syntax is a bit more convoluted, but doable:
int (*p)[w] = new int [size][w];
In both cases you would release memory with the same simple statement:
delete [] p;
The difference with the approaches doing double pointers (int **) is that the memory layout of the array is really that of an array of two dimensions, rather than a jump table into multiple separately allocated unidimensional arrays, providing better locality of data. The number of allocations is lower: one allocation vs. size + 1 allocations, reducing the memory fragmentation. It also reduces the potential from memory leaks (a single pointer is allocated, either you leak everything or you don't leak at all).
For a dynamic sized array you must dynamically allocate it. Instead of
int *a = new a[size][w];
Use
int** a = new int*[size];
for(int i = 0; i < size; i++)
a[i] = new int[w];
OP is saying he wants to create a 2 dimensional array where one dimension is already known and constant and the other dimension is dynamic.. Not sure if I got it right but here goes:
int main() {
const int w = 2;
int size = 10;
int* arr[w];
for (int i = 0; i < w; ++i)
arr[i] = new int[size];
//do whatever with arr..
//std::cout<<arr[0][0];
for (int i = 0; i < w; ++i)
for (int j = 0; j < size; ++j)
std::cout<<arr[i][j];
for (int i = 0; i < w; ++i)
delete[] arr[i];
return 0;
}
You can not do that in c++, please read about dynamic memory allocation
the code below should work
int* twoDimentionalArray = new [size*w]
I have this 3D matrix I allocated as one block of memory, but when I try to write to the darn thing, it gives me a segmentation fault. The thing works fine for two dimensions, but for some reason, I'm having trouble with the third...I have no idea where the error is in the allocation. It looks perfect to me.
Here's the code:
phi = new double**[xlength];
phi[0] = new double*[xlength*ylength];
phi[0][0] = new double[xlength*ylength*tlength];
for (int i=0;i<xlength;i++)
{
phi[i] = phi[0] + ylength*i;
for (int j=0;j<ylength;j++)
{
phi[i][j] = phi[i][0] + tlength*j;
}
}
Any help would be greatly appreciated. (Yes, I want a 3D matrix)
Also, this is where I get the segmentation fault if it matters:
for (int i = 0; i < xlength; i++)
{
for (int j = 0; j < ylength; j++)
{
phi[i][j][1] = 0.1*(4.0*i*h-i*i*h*h)
*(2.0*j*h-j*j*h*h);
}
}
This does work for two dimensions though!
phi = new double*[xlength];
phi[0] = new double[xlength*ylength];
for (int i=0;i<xlength;i++)
{
phi[i] = phi[0] + ylength*i;
}
You did not allocate other submatrixes like e.g. phi[1] or phi[0][1]
You need at least
phi = new double**[xlength];
for (int i=0; i<xlength; i++) {
phi[i] = new double* [ylength];
for (int j=0; j<ylength; j++) {
phi[i][j] = new double [zlength];
for (k=0; k<zlength; k++) phi[i][j][k] = 0.0;
}
}
and you should consider using std::vector (or even, if in C++2011, std::array), i.e.
std::vector<std::vector<double> > phi;
and then with std::vector you'll need to phi.resize(xlength) and a loop to resize each subelement phi[i].resize(ylength) etc.
If you want to allocate all the memory at once, you could have
double* phi = new double[xlength*ylength*zlength]
but then you cannot use the phi[i][j][k] notation, so you should
#define inphi(I,J,K) phi[(I)*xlength*ylength+(J)*xlength+(K)]
and write inphi(i,j,k) instead of phi[i][j][k]
Your second code does not work: it is undefined behavior (it don't crash because you are lucky, it could crash on other systems....), just some memory leak which don't crash yet (but could crash later, perhaps even by re-running the program again). Use a memory leakage detector like valgrind
I have been working on this program for quite some time. This is just two of the functions extracted that are causing a memory leak that I cant seem to debug. Any help would be fantastic!
vector<int**> garbage;
CODE for deleting the used memory
void clearMemory()
{
for(int i = 0; i < garbage.size(); i++)
{
int ** dynamicArray = garbage[i];
for( int j = 0 ; j < 100 ; j++ )
{
delete [] dynamicArray[j];
}
delete [] dynamicArray;
}
garbage.clear();
}
CODE for declaring dynamic array
void main()
{
int ** dynamicArray1 = 0;
int ** dynamicArray2 = 0;
dynamicArray1 = new int *[100] ;
dynamicArray2 = new int *[100] ;
for( int i = 0 ; i < 100 ; i++ )
{
dynamicArray1[i] = new int[100];
dynamicArray2[i] = new int[100];
}
for( int i = 0; i < 100; i++)
{
for(int j = 0; j < 100; j++)
{
dynamicArray1[i][j] = random();
}
}
//BEGIN MULTIPLICATION WITH SELF AND ASSIGN TO SECOND ARRAY
dynamicArray2 = multi(dynamicArray1); //matrix multiplication
//END MULTIPLICATION AND ASSIGNMENT
garbage.push_back(dynamicArray1);
garbage.push_back(dynamicArray2);
clearMemory();
}
I stared at the code for some time and I can't seem to find any leak. It looks to me there's exactly one delete for every new, as it should be.
Nonetheless, I really wanted to say that declaring an std::vector<int**> pretty much defies the point of using std::vector itself.
In C++, there are very few cases when you HAVE to use pointers, and this is not one of them.
I admit it would be a pain to declare and use an std::vector<std::vector<std::vector<int>>> but that would make sure there are no leaks in your code.
So I'd suggest you rethink your implementations in term of objects that automatically manage memory allocation.
Point 1: If you have a memory leak, use valgrind to locate it. Just like blue, I can't seem to find a memory leak in your code, but valgrind will tell you for sure what's up with your memory.
Point 2: You are effectively creating a 2x100x100 3D array. C++ is not the right language for this kind of thing. Of course, you could use an std::vector<std::vector<std::vector<int>>> with the obvious drawbacks. Or you can drop back to C:
int depth = 2, width = 100, height = 100;
//Allocation:
int (*threeDArray)[height][width] = malloc(depth*sizeof(*threeDArray));
//Use of the last element in the 3D array:
threeDArray[depth-1][height-1][width-1] = 42;
//Deallocation:
free(threeDArray);
Note that this is valid C, but not valid C++: The later language does not allow runtime sizes to array types, while the former supports that since C99. In this regard, C is more powerful than C++.
I am working with a multidimensional array but i get an exception, i have searched a lot but i find the same answer i'm using, the exception jumps when i try to allocate matriz[i] = new double[n]. I have tried both the commented and uncommented solutions with no luck.
void interpol(double *arr_x, double *arr_y, int n, double *results) {
//double** matriz = new double*[n];
double** matriz;
matriz = (double**) malloc(n * sizeof(double*));
for(int i = 0; i < n; i++){
//matriz[i] = new double[n+1];
matriz[i] = (double*) malloc(n+1 * sizeof(double));
for(int j = 0; j < n; j++) {
matriz[i][j] = pow(arr_x[i],j);
}
matriz[i][n] = arr_y[i];
}
gaussiana(matriz, n, results);
}
--- EDIT---
The function gaussiana is working fine, since i have tested outside this function. The exception is thrown in either:
//matriz[i] = new double[n];
matriz[i] = (double*) malloc(n * sizeof(double));
n is never more than 10.
The exception thrown is:
First-chance exception at 0x00071c4d in Interpolacion.exe: 0xC0000005:
Access violation reading location 0x00000000.
Unhandled exception at 0x774b15de in Interpolacion.exe: 0xC0000005: Access violation reading location 0x00000000.
The program '[8012] Interpolacion.exe: Native' has exited with code -1073741819 (0xc0000005).
----EDIT----
I finally got it working, the issue was not in matriz, but with arr_x/arr_y, the external routine was sending the data wrong (oddly the error and the stacktrace always referred me to the new double[n] assignation)
If you want to use the std::vector route, you can use something like below (untested, shown just as a guide). Keep in mind that std::vector<std::vector<double> > is not compatible with double **, so your gaussiana function might need to be rewritten to accept the new type.:
// Include the header!
#include <vector>
// Be careful about the use of "using namespace std", I'm only using it here
// because it's a small example
using namespace std;
vector<vector<double> > matriz;
for (int i = 0; i < n; i++)
{
// Create a new vector "v" with n+1 elements
vector<double> v(n + 1);
// fill this vector
for (int j = 0; j < n; j++)
v[j] = pow(arr_x[i], j);
v[n] = arr_y[i];
// add it to the matrix
matriz.push_back(v);
}
I don't see anything in the code present which would cause an exception. It must be gaussiana() causing the trouble. Try commenting that line out and see if the program still faults.
It would be useful to know the range of n. As long as it is relatively small (< 1000) on modern 32- or 64-bit machines, malloc() should not fail. However, if the program runs with restricted memory, or n is large, it is likely that some mallocs would fail. Since there is no checking for NULL being returned, the program would indicate trouble by SEGFAULTing when trying to dereference the pointer.
If the function is called multiple times, the memory leaking could add up to a significant heap shortage and induce malloc() to fail.