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
Related
I am currently learning how to utilize raw pointers in C++. I understand how to dynamically allocate a 2D array, however, as an exercise for myself, I attempted to apply my understanding of multiple levels of indirection to allocate a 3D array. My attempt is presented below:
int main() {
double*** matrix { new double**[10] {} };
for (size_t i {}; i < 10; ++i) {
matrix[i] = new double*[i + 1] {};
for(size_t j {}; j < 10; ++j) {
matrix[i][j] = new double[i + 1] {};
}
}
std::cout << matrix[0][0][0] << std::endl;
for (size_t i {}; i < 10; ++i) {
for (size_t j {}; j < 10; ++j) {
delete[] matrix[i][j];
matrix[i][j] = nullptr;
}
delete[] matrix[i];
matrix[i] = nullptr;
}
delete[] matrix;
matrix = nullptr;
return 0;
}
Since I'm using uniform initialization, matrix[0][0][0] should print the value 0.0; However, I'm getting a garbage value when doing so. Furthermore, I have a double free or corruption (out) error, which I assume is telling me that I am attempting to free memory from the same address twice.
Any help or guidance would be appreciated. I'm just trying to fully understand raw pointers.
Edit: I understand that double*** is not actually a 3D array. I'm just trying to utilize simple terminology.
matrix[i] = new double*[i + 1] {};
for(size_t j {}; j < 10; ++j) {
This is your error right here, you allocate an array of 'i + 1' element and then loop for 10, you either need to have i + 1 in both places or 10 otherwise this is undefined behavior. The same applies for deletion (the loop checks for 10 but you only allocated i + 1).
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));
}
I have a function which returns a 2D array in c++ as follows
float** Input_data(float** train_data, int Nv, int N){
float** x_train=new float*[Nv];
int a = 0,b = 0;
for(a = 1;a<= Nv;a++){
x_train[a] = new float[N+1];
for(b = 1; b <= N+1; b++){
if(b == 1){
x_train[a][b] = 1;
}else{
x_train[a][b] = train_data[a][b-1];
}
}return x_train;}
the purpose of the above code is to add ones in the first column and add remaining data from train_data pointer into x_train. after processing and using x_train i am trying to deallocate x_train as follows
void destroyx_array(float**x_train,int Nv){
for (int free_x = 1;free_x <= Nv;free_x++){
delete[] x_train[free_x];}delete[] x_train;}
and calling the destroy function as follows
destroyx_array(x_train,Nv)
the Input_data functions works fine but when i try to destroy_x_array it gives me double free or corruption(out) aborted (core dumped) can anybody explain what wrong i am doing ? thank you
Simply put, your code corrupts memory. The best thing is to not use raw pointers and instead use container classes such as std::vector.
Having said that, to fix your current code, the issue is that you're writing beyond the bounds of the memory here:
for(a = 1;a<= Nv;a++)
when a == Nv, you are writing one "row" beyond what was allocated. This looks like a manifestation of attempting to fake 1-based arrays. Arrays in C++ start from 0, not 1. Trying to fake 1-based arrays invariably can lead to bugs and memory corruption.
The fix is to rewrite your function to start from 0, not 1, and ensure your loop iterates to n-1, where n is the total number of rows:
for (a = 0; a < Nv; ++a)
the purpose of the above code is to add ones in the first column and
add remaining data from train_data pointer into x_train
Instead of the loop you wrote to test for the first column, you could simplify this by simply using memcpy:
for (int i = 0; i < Nv; ++i)
{
x_train[i][0] = 1;
memcpy(&x_train[i][1], &train_data[i][0], N * sizeof(float));
}
Thus the entire function would look like this:
float** Input_data(float** train_data, int Nv, int N)
{
float** x_train=new float*[Nv];
for(int a = 0; a < Nv; a++)
x_train[a] = new float[N+1];
for (int a = 0; a < Nv; a++)
{
x_train[i][0] = 1;
memcpy(&x_train[i][1], &train_data[i][0], N * sizeof(float));
}
return x_train;
}
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 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++.