Dynamic matrix in C++ - 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.

Related

Program received Segmentation fault while debug in CLion

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));
}

c++ malloc and two-dimension array not reserving enough memory

I need to creat a 2 dimension array with malloc, so that I can return it's pointer with a function. In this function I also allocate integers (by getpixel() function) into this array. I do it this way:
int **tab;
tab = (int**)malloc((600) * sizeof(int));
for (int i = 0; i<600; i++)
{
tab[i] = (int*)malloc((800) * sizeof(int*));
}
for (int i = 0; i<600; i++)
{
for (int j = 0; j<800; j++)
{
tab[i][j] = getpixel(i, j);
}
}
This array works of course in most of the cases, when I check it, it has the values I expected inside. However, it stops working, when I get to a bigger Y. So eg. when I want to check array tab[799][599], I can't, because there is an error about exception, I can't copy it directly, because I have the other language than English verion, but it goes something like that:
"The unsupported exception in 0x00E71C05 w bgi.exe: 0xC0000005: violation of rules of access when reading from the location 0x0000095C."
I think it means, that mallock() didn't reserve enought memory for me. But how can I make array big enough then? Or is this any other problem?
Your malloc is wrong, it needs to be like:
int **tab;
tab = (int**)malloc((800) * sizeof(int*));
for (int i = 0; i<800; i++)
{
tab[i] = (int*)malloc((600) * sizeof(int));
}
If you want your array to be 800x600. If you want it to be 600x800 just swap the values.

why terminate called after throwing an instance of 'std::bad_alloc'?

Every 1 second, function works.
my system the linux.
Runs suddenly dies.
-----global-------
static int arrayNum[33000];
-------------------
function(){
unsigned short int** US_INT;
US_INT= new unsigned short int*[255];
for(int i = 0; i < 255; i++)
{
US_INT[i] = new unsigned short int[128];
memset(US_INT[i], 0, sizeof(unsigned short int) * 128);
}
double x;
double y;
int cnt= 0;
int nArrayCount=0;
for(int i = 0; i < 255; i++)
{
for(int j=0;j<128;j++){
x=j;
y=cnt
nArray[nArrayCount]=US_INT[i][j];
nArrayCount++;
}
cnt=cnt+(256/255);
}
for(int i = 0; i < 255; i++)
{
delete US_INT[i];
}
delete[] US_INT;
}
program stop. and message↓
terminate called after throwing an instance of 'std::bad_alloc' what(): std::bad_alloc
The bad_alloc exception is triggered by a failure in the memory allocation (so one of your new). terminate() is called automatically because you don't catch this exception.
The root cause of the bad_alloc is that you don't have enough memory (or the free store is corrupted). This could for example happen if you reapeatedly fail to free memory in some loops.
In fact, in your code, it appears that you don't delete correctly the arrays US_INT[i] . Your must use delete[]US_INT[i]. As a general rule, every time you use new[], you shall use delete[].
P.S.: You could also opt for vectors instead of arrays and free your mind from memory maangement issues.

incorrect checksum for freed object

I am getting this error (memory location varies between runs):
q2(4910,0x7fff7a1d4300) malloc: *** error for object 0x7fdf79c04bd8: incorrect checksum for freed object - object was probably modified after being freed.
*** set a breakpoint in malloc_error_break to debug
Abort trap: 6
This is the function that crashes:
public:
// construct a 'rows X cols' matrix.
SMatrix(int rows, int cols) {
if (rows<1 || cols<1) {
cout<<"Invalid row/col value(s).";
exit(-1);
}
this->_rows = rows;
this->_cols = cols;
this->_vertical = new simpleNode [rows];
this->_horizontal = new simpleNode [cols];
if (this->_vertical == NULL || this->_horizontal==NULL) {
cout<<"Exiting";
exit(-1);
}
initArrays();
}
It crashes on this particular line:
this->_horizontal = new simpleNode [cols];
The function that calls:
int main() {
SMatrix bigM(500,500);
bigM.setElement(10,20,17);
cout <<" bigM - total size in bytes: (implementation depended): "
<< bigM.sizeInBytes() << endl << endl;
SMatrix m1(7,10),m2(7,10),m4(10,2),m5(7,2); //Crashes on m4(10,2)
}
Other functions that could be relevant:
struct simpleNode {
Node* _next;
};
int _rows; //Number of rows in this SMatrix
int _cols; //Number of columns in this SMatrix
simpleNode * _vertical; //array (simpleNode)
simpleNode * _horizontal; //array (simpleNode)
/*Initiate the horizontal/vertical arrays to point to null*/
void initArrays() {
int i;
for (i=0; i<this->_rows; i++)
this->_horizontal[i]._next = NULL;
for (i=0; i<this->_cols; i++)
this->_vertical[i]._next = NULL;
}
I am on OSX. I compiled with -g and ran it with GDB but Program exited normally.
How can I debug this if I don't use XCode? Also a hint on how to fix the problem would be very helpful.
Edit: I'm running the output file and sometimes it runs while others it gives me the error. Seems to be at a random order. Also, the program never fails when I run it on gdb it always exits correctly. Why is this happening?
Your limits are reversed in your initialization code. You create your arrays like this:
this->_vertical = new simpleNode [rows]; // <== uses rows for sizing vertical
this->_horizontal = new simpleNode [cols]; // <== uses cols for sizing horizontal
But your initialization does this:
for (i=0; i<this->_rows; i++) // <== limit is rows, but you walking horizontal
this->_horizontal[i]._next = NULL;
for (i=0; i<this->_cols; i++) // <== limit is cols, but you walking vertical
this->_vertical[i]._next = NULL;
Unless rows and cols are the same value, this code invokes undefined behavior. Fix this by using the same values as you sized your allocation with
for (i=0; i<this->_rows; i++)
this->_vertical[i]._next = NULL;
for (i=0; i<this->_cols; i++)
this->_horizontal[i]._next = NULL;
Honestly a much better approach would use RAII containers such as std::vector<>, but I leave that as an exercise for you.
Best of luck, and hope it helps.
Since you're in the debugger, you should look at the memory location 0x7fff7a1d4300 and see what's there. The data in memory may be helpful in figuring out what's going wrong.
What's happening is one of the following:
you are freeing an object twice,
you are freeing a pointer that was never allocated
you are writing through an invalid pointer which previously pointed to an object which was already freed
I think what happens is No.3.
My answer is based in this answer.
A relevant discussion lies here.
Relevant question about gdb.

C++ Segmentation Fault After When Trying to Write to Matrix

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