Copying a dynamically allocated 2D array - c++

I have a question as follows:
I declared two pointer-to-pointer double-type variables **matrix1 and **matrix2 and allocate them by new operator to become 2D arrays.
First I used for loop to make matrix1 point to double-type data called element, then I copy matrix1 to matrix2, which means matrix2 points to element too. Then problem comes: I used delete operator to terminate matrix1 after copying, but then the values matrix2 point to became extremely strange. I think that was because after deleting matrix1, element terminates, so I think one of a solution is let matrix2 point to other address with the values same with element. But I don't know how to do this(copy element to new dynamic memories and won't disappear after deleting matrix1) in an efficient way, can somebody help me? thank you.
void MatCpy(double **InMat, double **OutMat, int NumOfRow, int NumOfCol)
{
for (int j = 0; j < NumOfRow; j++)
{
for (int i = 0; i < NumOfCol; i++)
{
OutMat[j][i] = InMat[j][i];
}
}
}
double **Malloc2D_Dbl(int row, int col)
{
double **data = new double*[row];
for (int i = 0; i < row; i++)
data[i] = new double[col];
return data;
}
void load(char *load_path, double **data, int height, int width) // function for loading
{
int i = 0, j = 0;
char buffer[30];
file_handle = fopen (load_path, "r");
for (int k = 0; k < width*height; k++)
{
fscanf (file_handle, "%s", &buffer);
j = k / width;
i = k % width;
data[j][i] = atof(buffer);
}
fclose (file_handle);
}
Sorry I am a noob....

More efficient than copying the individual elements is to use memcpy like this:
void MatCpy(double **InMat, double **OutMat, int NumOfRow, int NumOfCol) {
for(int j=0; j<NumOfRow; j++) {
memcpy(OutMat[j], InMat[j], NumOfCol*sizeof(double));
}
}

Related

Weird "e+08" values doing resizing of an 2D dynamic array

Im trying to do a function that resizes a matrix made of dynamic arrays given 2 parametres: the new amount of rows and the new amount of columns. My problem is that when I size it to a larger matrix than the original one the new values that should be 0 are something like -4.31602e+08. Shouldn't be 0 if i don't set a value and just initialize the array?
void Matrix::resize(int nRows, int nColumns) {
float** aux = new float* [nRows];
for (int i = 0; i < nRows;i++) {
aux[i] = new float[nColumns];
}
for (int i = 0; i < m_nRows; i++) {
for (int j = 0; j < m_nColumns; j++) {
if (i < nRows && j < nColumns) {
aux[i][j] = m_matrix[i][j];
}
}
}
for (int i = 0; i < m_nRows; ++i)
delete[] m_matrix[i];
delete[] m_matrix;
m_matrix = aux;
m_nRows = nRows;
m_nColumns = nColumns;
}
You incorrectly assume that a float is initialized at 0.
Try to compile the following code
float f;
std::cout << f;
.. compiler at least says "warning: 'f' is used uninitialized". But probably prints 0 after all.
Now try
float* fp = new float;
std::cout << *fp;
delete fp;
Compiler doesn't warn, but you are printing random memory contents...
Accessing uninitialized variables is undefined behavior.
edit: a smart pointer will initialize the value for you by the way
auto fp = std::make_unique<float>();
std::cout << *fp << '\n';

multiplying two arrays of different dimensions in c++

for my assignment I have to multiply two matrices together to create a new one. I will then sort the new one from an inherited class. My question is what is the format to multiply two arrays of different dimensions my first one a1d is 5 integers. My other one a2d is a 5x10 array. What is the correct way to multiply these together being that they are different sizes and dimensions. Do I multiply a1d by every row of a2d? I am going to output the products to a 1 dimensional array so that sorting is easier. I have drawn out the two arrays as tables to help me visualize it. I will attach the short code I have and my illustration. This is in C++.
#pragma once
#include<ctime>
#include<iostream>
#include<cmath>
using namespace std;
class matrices
{
private:
int* a1d[5]; // Old Code:int* a1d = new int[5];
int** a2d = new int* [5];
public:
int* matrix;
matrices();
~matrices();
int* filla1d();
int* filla2d();
int* multiply();
};
int* matrices::filla1d() {
for (int i = 0; i < 5; i++) {
a1d[i] = new int;
}
for (int i = 0; i < 5; i++) {
*a1d[i] = rand() % 10 + 1;
}
return *a1d;
}
int* matrices::filla2d() {
for (int i = 0; i < 5; i++) {
a2d[i] = new int[10];
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 10; j++) {
a2d[i][j] = rand() % 10 + 1;
cout << a2d[i][j] << endl;
}
}
return *a2d;
}
int* matrices::multiply() {
}
it is required that I only use pointer type variables and pointer returning functions, though that doesn't change too much. I don't know how they should be multiplied, and because of that, I am not sure how many values will be generated from the multiplication for the size of the new array. Thanks in advance!
Here is what I have designed to multiply them together. I have changed how my pointer arrays are allocated. My problem now is that it tells me that "expression must have arithmetic or unscoped enum type". Where I have matrix[i] =(a1d[index1] * a2d[index1][index2]); I thought maybe a1d needed to be a pointer type but it gives me the error where it can't convert from int* to int.
Also, when I debug, my a1d and matrix arrays allocate perfectly and show the correct number of data slots when moused over. However, a2d only shows one pointer which points to 5 in this case. I followed the syntax I have seen online for an array of pointers to create a 2d array.
int* matrices::filla1d() {
for (int i = 0; i < 5; i++) {
a1d[i] = new int;
}
for (int i = 0; i < 5; i++) {
*a1d[i] = rand() % 10 + 1;
}
return *a1d;
}
int* matrices::filla2d() {
for (int i = 0; i < 5; i++) {
a2d[i] = new int[10];
}
for (int i = 0; i < 5; i++) {
for (int j = 0; j < 10; j++) {
a2d[i][j] = rand() % 10 + 1;
}
}
return *a2d;
}
int* matrices::multiply() {
for (int i = 0; i < 50; i++) {
matrix[i] = new int;
}
int index1 = 0;
int index2 = 0;
for (int i = 0; i < 50; i++) {
matrix[i] = (a1d[index1] * a2d[index1][index2]);
index1++;
index2++;
}
return *matrix;
}
class matrices
{
private:
int* a1d[5];
int** a2d = new int*[5];
public:
int* matrix[50];
matrices();
~matrices();
int* filla1d();
int* filla2d();
int* multiply();
};
Edit 2:
I changed the line to fill up the new matrix to say
*matrix[i] = a2d[index1][index2] * *a1d[index1];
Now I get an access violation error on this line. I have matrix allocated the same way I have a1d allocated, what can cause my access violation?

Access violation reading from double pointer [duplicate]

I have a 2-dimensional array and I am passing it into a function to carry out certain operations. I'd like to know the correct way of doing it...
#define numRows 3
#define numCols 7
#define TotalNum (numRows*numCols)
int arr[numRows][numCols] = {{0,1,2,3,4,5,6}, {7,8,9,10,11,12,13},{14,15,16,17,18,19,20}};
void display(int **p)
{
printf("\n");
for (int i = 0; i< numRows;i++)
{
for ( int j = 0;j< numCols;j++)
{
printf("%i\t",p[i][j]);
}
printf("\n");
}
}
int main() {
display(arr);
}
I get an error message:
'display': cannot convert parameter1 from 'int' to 'int*'
Is this the correct way of passing a 2-dimensional array into a function? If not, what is the correct way?
You should declare your function like this:
void display(int p[][numCols])
This C FAQ thoroughly explains why. The gist of it is that arrays decay into pointers once, it doesn't happen recursively. An array of arrays decays into a pointer to an array, not into a pointer to a pointer.
If (like in your case), you know the dimensions of the array at compilation-time, you can write justvoid display(int p[][numCols]).
Some explanation: You probably know that when you pass an array to a function, you actually pass a pointer to the first member. In C language, 2D array is just an array of arrays. Because of that, you should pass the function a pointer to the first sub-array in the 2D array. So, the natural way, is to say int (*p)[numCols] (that means p is a pointer, to an array of numCols ints). In function declaration, you have the "shortcut" p[], that means exactly the same thing like (*p) (But tells the reader, that you pass a pointer to a beginning of array, and not to just an one variable)
There are several, sometimes equivalent ways of doing this. By declaring an array (cf. method_c()), by using a pointer (cf. method_b()) or by using a pointer to an array of an array (cf. method_a()). method_b(), using a single pointer, is slightly more difficult to get right since it is not easy to use standard array indexing and hence, we use pointer arithmetic. method_a() and method_c() are basically equivalent since arrays decay non-recursively to pointers during compilation. Here is a little program illustrating all three methods. We first initialize a 2x4-array arr in a simple for loop and print it. It will look like this:
arr:
0 1 2 3
0 1 2 3
Afterwards we call all three methods. method_a() adds 1, method_b() adds 2 and method_c() adds 3 to all elements. After each call we print out the array arr again. If a function worked correctly you will easily see it on the output. Size is arbitrary and can be regulated via the two macros ROW and COL. One last note, method_c() relies on variable-length array present since C99.
#include <stdio.h>
#include <stdlib.h>
#define ROW 2
#define COL 4
void method_a(int m, int n, int (*ptr_arr)[n]);
void method_b(int m, int n, int *ptr_arr);
void method_c(int m, int n, int arr[][n]);
int main(int argc, char *argv[]) {
int arr[ROW][COL];
int i;
int j;
for(i = 0; i < ROW; i++) {
for(j = 0; j < COL; j++) {
arr[i][j] = j;
}
}
printf("Original array:\n");
for (i = 0; i < ROW; i++) {
for(j = 0; j < COL; j++) {
printf("%d\t", arr[i][j]);
}
printf("\n");
}
printf("\n\n");
method_a(ROW, COL, arr);
printf("method_a() array:\n");
for (i = 0; i < ROW; i++) {
for(j = 0; j < COL; j++) {
printf("%d\t", arr[i][j]);
}
printf("\n");
}
printf("\n\n");
printf("method_b() array:\n");
method_b(ROW, COL, (int *)arr);
for (i = 0; i < ROW; i++) {
for(j = 0; j < COL; j++) {
printf("%d\t", arr[i][j]);
}
printf("\n");
}
printf("\n\n");
method_c(ROW, COL, arr);
printf("method_c() array:\n");
for (i = 0; i < ROW; i++) {
for(j = 0; j < COL; j++) {
printf("%d\t", arr[i][j]);
}
printf("\n");
}
printf("\n\n");
return EXIT_SUCCESS;
}
void method_a(int m, int n, int (*ptr_arr)[n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
ptr_arr[i][j] = j + 1;
}
}
}
void method_b(int m, int n, int *ptr_arr)
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
/* We need to use pointer arithmetic when indexing. */
*((ptr_arr + i * n) + j) = j + 2;
}
}
/* The whole function could have also been defined a bit different by taking
* the i index out of the pointer arithmetic. n alone will then provide our
* correct offset to the right. This may be a bit easier to understand. Our
* for-loop would then look like this:
* for (i = 0; i < m; i++)
* {
* for (j = 0; j < n; j++)
* {
* *((ptr_arr + n) + j) = j + 2;
* }
* ptr_arr++;
* }*/
}
void method_c(int m, int n, int arr[][n])
{
int i, j;
for (i = 0; i < m; i++)
{
for (j = 0; j < n; j++)
{
arr[i][j] = j + 3;
}
}
}
You are doing in wrong way. You can pass 2-d array with the help of pointer to an array, or simply pass an array or through Single pointer.
#define numRows 3
#define numCols 7
void display(int (*p)[numcols],int numRows,int numCols)//First method//
void display(int *p,int numRows,int numCols) //Second Method//
void display(int numRows,int numCols,int p[][numCols]) //Third Method
{
printf("\n");
for (int i = 0; i < numRows;i++)
{
for ( int j = 0; j < numCols;j++)
{
printf("%i\t",p[i][j]);
}
printf("\n");
}
}
int main() {
display(arr,numRows,numCols);
}
Declare it simply
void display(int (*p)[numCols][numRows]);
This way your p pointer conveys all necessary informations and you can extract all the dimensions from it without repeating numCols and numRows over and over.
void display(int (*p)[numCols][numRows])
{
size_t i, j;
printf("sizeof array=%zu\n", sizeof *p);
printf("sizeof array[]=%zu\n", sizeof **p);
printf("sizeof array[][]=%zu\n", sizeof ***p);
size_t dim_y = sizeof *p / sizeof **p;
printf("dim_y = %zu\n", dim_y);
size_t dim_x = sizeof **p / sizeof ***p;
printf("dim_x = %zu\n", dim_x);
for(i=0; i<dim_y; i++) {
puts("");
for(j=0; j<dim_x; j++)
printf(" %6d", (*p)[i][j]);
}
}
This is particularly interesting if you use typedefs (which I don't like btw)
typedef int matrix[5][6];
In that case the dimensions are not visible in the signature of the function but the function will still have the correct values for the dimensions.
You can change the signature of display method as follows:
void display(int (*p)[numCols])
Here, p is a pointer to the row of a 2D array. The pointer only needs to know the number of columns in the array.
Actually speaking, pointer need to know the size of each row. This is very important for pointer arithmetic. So that when you increment the pointer, the pointer must point to next row.
Note here, p is not a normal integer pointer. It's a integer pointer to the memory size equal to integer_size x columns.
In main you don't need to change anything. display(arr) is just fine.

using delete is crashing my program

When I try to delete my pointers on distractor, my program is crashing, why?
I don't understand what I am doing wrong in my code.
Am I using new wrong?
class Matrix:
class Matrix
{
private:
double **_array;
int _rows, _cols;
...
Matrix::Matrix(int rows, int cols)
{
if (rows <= 0 || cols <= 0)
exit(-1);
this->_array = new double*[rows];
for (int i = 0; i < rows; i++)
this->_array[i] = new double[cols];
this->_rows = rows;
this->_cols = cols;
}
The problem is here:
void Matrix::pow(int power, Matrix& result)
{
/*if (result == NULL)
exit(-1);*/
if (result._cols != this->_cols || result._rows != this->_rows)
exit(-1);
// Can't pow the matrix, return mat of '0' values
if (this->_cols != this->_rows)
{
for (int i = 0; i < result._rows; i++)
for (int j = 0; j < result._cols; j++)
result.setElement(i, j, 0);
return;
}
/*if (power == 0)
result = 1;*/
double sum = 0;
Matrix temp(this->_rows, this->_cols);
// Copy this matrix to result matrix
for (int i = 0; i < this->_rows; i++)
for (int j = 0; j < this->_cols; j++)
result.setElement(i, j, this->_array[i][j]);
// Pow loop
for (int p = 1; p < power; p++)
{
for (int i = 0; i < this->_rows; i++)
for (int j = 0; j < this->_cols; j++)
{
for (int k = 0; k < this->_rows; k++)
sum += this->getElement(i, k) * result.getElement(k, j);
temp.setElement(i ,j ,sum);
sum = 0;
}
// Copy temp array to result array
for (int i = 0; i < this->_rows; i++)
for (int j = 0; j < this->_cols; j++)
result.setElement(i, j, temp.getElement(i, j));
for (int i = temp._rows; i >= 0; i--)
delete[] temp._array[i];
delete[] temp._array;
}
}
Main:
void main()
{
int rows = 3, cols = 3;
Matrix m1(rows, cols);
Matrix other(rows, cols);
Matrix result(rows, cols);
for (int i = 0; i < rows; i++)
for (int j = 0; j < cols; j++)
{
m1.setElement(i, j, i + j);
other.setElement(i, j, 3 * (i + j + 1));
}
m1.pow(3, result);
}
SetElements:
void Matrix::setElement(int i, int j, double data)
{
if (i < 0 || j < 0)
exit(-1);
if (i >= this->_rows || j >= this->_cols)
exit(-1);
_array[i][j] = data;
}
thanks
1) The word for member function that prepares an object to no longer exist is destructor, not distractor.
2) If you the array form of operator new, using the non-array form of operator delete - which you are - gives undefined behaviour. Use the array form of operator delete instead.
3) Your code, as shown, uses other functions that you have no provided. Any of those, if implemented incorrectly, could be doing an invalid operation on a pointer, and therefore be OTHER causes of your crash.
4) Don't bother to use dynamic memory allocation (operator new, etc) to work with dynamically allocated arrays. You have demonstrated that doing so is error prone. If you want a dynamically allocated array of double use a std::vector<double>. If you want a two dimensional array of double, use a std::vector<std::vector<double> >. Apart from being less error prone, a std::vector releases its memory correctly (as long as you don't write some other code which trashes memory).
In your Matrix, you allocate new arrays:
...
this->_array = new double*[rows]; // <== array of pointers
for (int i = 0; i < rows; i++)
this->_array[i] = new double[cols]; // <== arrays of doubles
...
But in your destructor you delete elements. You have to correct this: Everytime you alocate an array (new []), you have to delete the array (delete []), or you'll get undefined behaviour (for example crash):
for (int i = 0; i < _rows; i++)
delete[] _array[i]; // <== delete array, not element!!
delete[] _array; // <== delete array, not element!!
Note: that everytime you're tempted to use new/delete, you should ask yourself, if it wouldn't be worth to consider using vectors instead. It's very easy as this online demo show with your code reworked
Edit: your problem with pow():
Here you create the matrix object temp:
Matrix temp(this->_rows, this->_cols);
This object will be destructed automatically at the end of the function pow(). THis means that its destructor will call all the necessary delete[].
The problem is that at the end of the function, you manually do the job of the destructor, so you delete[] temp's arrays. Then the destructor tries to delete already deleted objects. This is undefined behaviour and hence the crash !
All you have to do is get rid of the 3 last lines of pow() and the unnecessary delete[] they contain.

Converting 2D vector to 2D array

It's been a while since I last visited arrays (I've been working with vectors recently) and I need to convert an 2D vector back into a 2D array because of a library I am using accepts the paramaters of type double array where the accessors of this array is foo[i][j] for example.
Here is my code:
double** setupHMM(vector<vector<double> > &vals, int N, int M)
{
double** temp;
temp = new double[N][M];
for(unsigned i=0; (i < N); i++)
{
for(unsigned j=0; (j < M); j++)
{
temp[i][j] = vals[i][j];
}
}
}
And with this, I get error: ‘M’ cannot appear in a constant-expression
I have also tried the following:
double** setupHMM(vector<vector<double> > &vals, int N, int M)
{
double** temp;
for(unsigned i=0; (i < N); i++)
{
temp[i] = new double[N];
for(unsigned j=0; (j < M); j++)
{
temp[j] = new double[M];
temp[i][j] = vals[i][j];
}
}
}
However, this produces a segmentation fault 11.
Could anyone suggest any advice, or, a better way to convert a vector to a 2D array..
Thanks
You were close. It should be:
double** setupHMM(vector<vector<double> > &vals, int N, int M)
{
double** temp;
temp = new double*[N];
for(unsigned i=0; (i < N); i++)
{
temp[i] = new double[M];
for(unsigned j=0; (j < M); j++)
{
temp[i][j] = vals[i][j];
}
}
}
A double pointer (double**) is not convertible to a 2D array.
double** temp;
temp = new double[N][M]; //invalid
double** temp;
temp = new double(*)[M];
It's a common misunderstanding to think that because an 1D array decays to a pointer that therefore a 2D array will decay to a double pointer. This is not true. The decay only happens with a single pointer.
replace
temp[i] = new double[N];
with
temp = new double*[N];
in the second code, and move it outside the loop