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