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

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';

Related

Exception assembly code error with a matrix to array function conversion call in main function

I'd like to convert a Matrix into an array, which I managed to do inside the main function, but when time to come to put it in a function, it stops working and I get an access violation error which didn't show inside the main scope.
Here is the code, I need help to complete the conversion. I need to cast it from a class function for my project.
#include <iostream>
const int rows = 3, cols = 4; //define constant rows and columns
int* MatrixToArray(static int* matrix[rows][cols]) {
int* array[rows*cols]{};//initialize the array
int* ptrResult=nullptr;//initialize the return variable
//First loop to fill the matrix with dissociated values to print out
for (int i = 0; i < rows-1; i++) {
for (int j = 0; j < cols-1; j++) {
if (matrix) {
*matrix[i][j] = i + j + i * (j + cols); ///exception violation access memory
}
if (matrix) {//debug warning C6011
std::cout << " [" << *matrix[i][j] << "]";
}
}
std::cout << ",\n";
}
//second reversed loop to get the unified array from the previous matrix
for (int u = 0; u < 1; u++) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (array) {//debug warning C6011
array[u] = matrix[i][j];
if (ptrResult) {//debug warning C6011
ptrResult = array[u];
}
}
std::cout << "[" << *array[u] << "] ";
}
}
}
free(array);
return ptrResult;
}
int main()
{
int* matrix[rows][cols];
std::cout << MatrixToArray(matrix);
}
After adapting the types for the matrix and the array, I get this code :
#include <iostream>
const int rows = 3, cols = 4; //define constant rows and columns
int* MatrixToArray(int** matrix) {
int* array[rows*cols]{};//initialize the array
int* ptrResult=nullptr;//initialize the return variable
//allocate memory as requested in the subedit comment field answers
matrix = new int* [rows];
for (int i = 0; i < rows; ++i)
matrix[i] = new int[cols];
//First loop to fill the matrix with dissociated values to print out
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix) {
matrix[i][j] = i + j + i * (j + cols); ///exception violation access memory disappear
}
if (matrix) {//debug warning C6011
std::cout << " [" << matrix[i][j] << "]";
}
}
std::cout << ",\n";
}
//second reversed loop to get the unified array from the previous matrix
if (array) {
for (int u = 0; u < 1; u++) {
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (array) {//debug warning C6011
array[u] = &matrix[i][j];
if (ptrResult) {//debug warning C6011
ptrResult = array[u];
}
}
//std::cout << "[" << *array[u] << "] ";
}
}
}
free(array);//File: minkernel crts ucrt src appcrt heap debug_heap.cpp Line:904 expression: _CrtlsValidHeapPointer(block)
}
return ptrResult;
}
int main()
{
//memory allocation correction
int** matrix;
matrix = new int* [rows];
for (int i = 0; i < rows; ++i)
matrix[i] = new int[cols];
std::cout << MatrixToArray(matrix);
}
I still get an exception error, but in the assembly code which ends up into the message copied in the comment next to the line quoted.
#include <iostream>
const int rows = 3, cols = 4; //define constant rows and columns
int* MatrixToArray(int** matrix) {
int* array= new int[rows * cols]{};//initialize the array (with new keyword)
int* ptrResult=nullptr;//initialize the return variable
matrix = new int* [rows];
for (int i = 0; i < rows; ++i)
matrix[i] = new int[cols];
std::cout << "[";
//First loop to fill the matrix with dissociated values to print out
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (matrix) {
matrix[i][j] = i + j + i * (j + cols); ///exception violation access memory disappeared
}
if (matrix) {//debug warning C6011
std::cout << " [" << matrix[i][j] << "]";
}
}
if (i != rows - 1) {
std::cout << ",\n";
}
}std::cout << "]";
//second reversed loop to get the unified array from the previous matrix
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
if (array) {//debug warning C6011
array[0] = matrix[i][j]; //modified with new initialization
if (ptrResult) {//debug warning C6011
*ptrResult = array[0];//modified with new initilization
}
}
}
}
delete[] array;
return ptrResult;
}
int main()
{
int** TheMatrix;
TheMatrix = new int* [rows];
for (int i = 0; i < rows; ++i)
TheMatrix[i] = new int[cols];
std::cout << MatrixToArray(TheMatrix);
for (int i = 0; i < rows; ++i) {
delete[] TheMatrix[i];
}
delete[] TheMatrix;
}
Finally, I tweaked the pointers, and I got rid of the exception in the assembly mode, But I get a serie of zeros popping out in the end...
I'd like to convert a Matrix into an array
Given what you have stated in your question, there is no need to turn a two-dimensional array into a one-dimensional array, if the two-dimensional array is either:
A "traditional" C++ array (i.e. int matrix[10][10];) or
A two-dimensional array built from a T** in a contiguous manner.
Both the items above have the same property, and that is the data is in contiguous memory, no different than a single dimension array. Thus a 2-dimensional array is already a 1 dimensional array.
The only difference between item 1 and item 2 above in terms of contiguousness is that item 1 is "pre-built", while item 2 requires you to build the two-dimensional array.
For item 2). the answer here shows a complete class that builds the matrix from any T** in a contiguous manner. The way you're building the 2-dimensional array does not create the data in contiguous memory, since each row is allocated separately.
Once you have the matrix, the way you use it in a one-dimensional fashion is to pass the address of the items to whatever function or entity requires a pointer to a one-dimensional array.
Here is an example (for the int**, we will use the code in the other linked answer).
#include <iostream>
#include <exception>
#include <numeric>
template <typename T>
T** create2DArray(unsigned nrows, unsigned ncols, const T& val = T())
{
if (nrows == 0)
throw std::invalid_argument("number of rows is 0");
if (ncols == 0)
throw std::invalid_argument("number of columns is 0");
T** ptr = nullptr;
T* pool = nullptr;
try
{
ptr = new T*[nrows]; // allocate pointers (can throw here)
pool = new T[nrows*ncols]{val}; // allocate pool (can throw here)
// now point the row pointers to the appropriate positions in
// the memory pool
for (unsigned i = 0; i < nrows; ++i, pool += ncols )
ptr[i] = pool;
// Done.
return ptr;
}
catch (std::bad_alloc& ex)
{
delete [] ptr; // either this is nullptr or it was allocated
throw ex; // memory allocation error
}
}
template <typename T>
void delete2DArray(T** arr)
{
delete [] arr[0]; // remove the pool
delete [] arr; // remove the pointers
}
// The MatrixToArray function takes a pointer to a buffer and prints the info
void MatrixToArray(int data[], int numItems)
{
for (int i = 0; i < numItems; ++i)
std::cout << data[i] << " ";
std::cout << "\n";
}
int main()
{
int test1[] = {1,2,3,4,5,6,7,8,9,10}; // a 1-dimensioanl array
int test2[2][5] = {{1,2,3,4,5},{6,7,8,9,10}}; // a 2-dimensional array
int **test3 = create2DArray<int>(2,5); // a dynamically created 2-d array
// quickly fill the above with the same data as the other arrays
std::iota(&test3[0][0], &test3[1][5], 1);
// Now test each one to prove that the same MatrixToArray function works for
// 1-dimensional and 2-dimensional arrays.
std::cout << "Output 1:\n";
MatrixToArray(test1, 10);
std::cout << "\nOutput 2:\n";
MatrixToArray(&test2[0][0], 10);
std::cout << "\nOutput 3:\n";
MatrixToArray(&test3[0][0], 10);
delete2DArray(test3);
}
Output:
Output 1:
1 2 3 4 5 6 7 8 9 10
Output 2:
1 2 3 4 5 6 7 8 9 10
Output 3:
1 2 3 4 5 6 7 8 9 10
The same output is produced from the MatrixToArray function, regardless if the array is one-dimensional, or if the array is 2-dimensional traditional, or 2-dimensional array built dynamically.

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?

Multidimensional Arrays initialized,What is differnce of Initialize with declarations and Initialize after declaration?

What is the difference of multidimensional array initialization?
This is 'Longest Common Subsequence' problem.
string str1, str2;
getline(cin, str1);
getline(cin, str2);
int alphaCount[26] = { 0, };
int str1Len = str1.length();
int str2Len = str2.length();
int** arr = new int* [str1Len+1];
for (int i = 0; i < str1Len+1; i++)
{
arr[i] = new int[str2Len+1];
//Method One
for (int j = 0; j < str2Len+1; j++)
{
arr[i][j] = 0;
}
}
for (int i = 0; i < str1Len; i++)
{
for (int j = 0; j < str2Len; j++)
{
int y = i + 1;
int x = j + 1;
if (str1[i] == str2[j])
arr[y][x] = arr[y - 1][x - 1] + 1;
else
{
if (arr[y][x - 1] > arr[y - 1][x])// using uninitialized memory ERROR
arr[y][x] = arr[y][x - 1];
else
arr[y][x] = arr[y - 1][x];
}
}
}
cout << arr[str1.length()][str2.length()] << "\n";
// Method Two
// Not Error
for (int i = 0; i < str1Len + 1; i++)
{
for (int j = 0; j < str2Len + 1; j++)
{
arr[i][j] = 0;
}
}
// Method Three
//global valiable, Not Error
int arr[1001][1001];
Why Method One has error message
warning C6001: using uninitialized memory .
What is the difference between method 1 and method 2?
If there are more elements than numbers in the list, C++ pads the list with zeros. Thus this static array:
int alphaCount[26] = { 0, };
will have all its members initialized to zeroes (explicitly setting the first element to zero, and letting the others get automatically initialized).
This:
int** arr = new int* [str1Len+1];
for (int i = 0; i < str1Len+1; i++)
{
arr[i] = new int[str2Len+1];
for (int j = 0; j < str2Len+1; j++)
{
arr[i][j] = 0;
}
}
will also initialize all elements of the array to 0. However, in this case, the array is a 2D array, and is dynamically allocated (don't forget to free it afterwards). Typically you should check if new succeeded.
Note: Static array vs. dynamic array in C++.
The second method will initialize all the elements of the 2D array to zero, by using a double for loop.
The third method will initialize the global array's elements to zeroes, since Why are global and static variables initialized to their default values?

Copying a dynamically allocated 2D array

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

C++ 2D dynamic array allocation

I have a float** array that contains num_rows rows and num_cols columns. I'd like to determine the number of occurrences of every number between 0-9 columnwise. To do this, I thought of using another 2D array of size [10][num_cols], so that for each column the number corresponding to an element is the number of occurrences of that number in the original table.
Example: if the original table contains 1 2 3 1 1 in the fifth column, then in the second column, the values should be like: 1-> 3, 2 -> 1, 3 -> 1.
I tried using the function as follows, but it gives me a pointer error. I tried using vectors but that too brings no luck.
int ** attribute_count(float * * input, int row_num, int col_num) {
int ** arr_2 = new int * [10];
int * arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i][j] = 0;
}
}
for (int i = 0; i < 9; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
EDIT:
I tried your suggestions. The new code is:
int** attribute_count(float** input, int row_num, int col_num) {
int** arr_2 = new int* [10];
int* arr = new int[10 * col_num];
int counter = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
arr_2[i] = new int[col_num];
}
}
for (int i = 0; i < 11; i++) {
for (int j = 0; j < col_num; j++) {
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}
This still gives me memory errors. The function is being called in the .cpp like this:
int** attr = attribute_count(training_data, 10, num_cols_train);
cout<<attr[5][1];
Any idea what I'm doing wrong even now?
I think your problem is in incorrect allocation of the 2D array. Try
int ** arr_2 = new int* [row_num];
for (int i = 0; i < row_num; i++)
arr_2[i] = new int[col_num];
You've only allocated one dimension of arr_2. You need to loop through and allocate an array of ints on each one to get the 2nd dimension.
EDIT: Also, what's up with arr? You allocate it, never use it, don't return it, and don't deallocate it. That's how we spell memory leak.
arr_2 is defined and allocated as an array of pointers to int, but you don't actually assign/allocate those pointers.
Here's a stab at correcting your code - however I'm not convinced you have rows and columns the right way around...
int ** attribute_count(float ** input, int row_num, int col_num)
{
int ** arr_2 = new int * [10];
for (int i = 0; i < 10; i++)
{
arr_2[i] = new int[col_num];
for(int j = 0 ; j < col_num ; j++)
{
arr_2[i][j] = 0;
}
}
for (int i = 0; i < row_num; i++)
{
for (int j = 0; j < col_num; j++)
{
int temp = input[i][j];
arr_2[temp][j]++;
}
}
return arr_2;
}