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?
Related
So I got a function which creates me 2D array and fill it with test data.
Now I need to assign the pointer to an array
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
int arr[m][n];
//Algorithm - transpose
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++){
arrT[j][i] = arr[i][j];
}
}
Is there any way of doing this?
There are at least four problems with the function.
//Fill matrix with test data
int *testArrData(int m, int n){
int arr[n][m];
int* ptr;
ptr = &arr[0][0];
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
return (int *) arr;
}
First of all you declared a variable length array
int arr[n][m];
Variable length arrays are not a standard C++ feature.
The second problem is that these for loops
for(int i = 0; i < m; i++){
for(int j = 0; j < n; j++){
*((ptr+i*n)+j) = rand()%10;
}
}
are incorrect. It seems you mean
for(int i = 0; i < n; i++){
for(int j = 0; j < m; j++){
*((ptr+i*m)+j) = rand()%10;
}
}
You are returning a pointer to a local array with automatic storage duration that will not be alive after exiting the function. So the returned pointer will be invalid.
And arrays do not have the assignment operator.
Instead use the vector std::vector<std::vector<int>>. For example
std::vector<std::vector<int>> testArrData(int m, int n){
std::vector<std::vector<int>> v( n, std::vector<int>( m ) );
for ( auto &row : v )
{
for ( auto &item : row )
{
item = rand() % 10;
}
}
return v;
}
This is how I would accomplish this. I agree with int ** because it is easy to understand if you dont know how to use vectors. Also, the rand() can cause trouble if you are using the result to index an array. Make sure to use abs(rand() % number) if you don't want negative numbers.
I've updated the answer due to some vital missing code.
// This method creates the overhead / an array of pointers for each matrix
typedef int* matrix_cells;
int **create_row_col_matrix(int num_rows, int num_cols, bool init_rnd)
{
num_rows = min(max(num_rows, 1), 1000); // ensure num_rows = 1 - 1000
num_cols = min(max(num_cols, 1), 1000); // ensure num_cols = 1 - 1000
int *matrix_total = new int[num_rows*num_cols];
// overhead: create an array that points to each row
int **martix_row_col = new matrix_cells[num_rows];
// initialize the row pointers
for (int a = 0; a < num_rows; ++a)
{
// initialize the array of row pointers
matrix_row_col[a] = &matrix_total[num_cols*a];
}
// assign the test data
if (init_rnd)
{
for (int run_y = 0; run_y < num_rows; ++run_y)
{
for (int run_x = 0; run_x < num_cols; ++run_x)
{
matrix_row_col[run_y][run_x] = abs(rand() % 10);
}
}
}
return matrix_row_col;
}
int src_x = 7, dst_x = 11;
int src_y = 11, dst_y = 7;
int **arr_src = create_row_col_matrix(src_y, src_x, true);
int **arr_dst = create_row_col_matrix(dst_y, dst_x, false);
for (int a = 0; a < dst_y; ++a)
{
for (int b = 0; b < dst_x; ++b)
{
arr_dst[a][b] = arr_src[b][a];
}
}
delete matrix_src[0]; // int *matrix_total = new int[src_y*src_x]
delete matrix_src; // int **matrix_row_col = new matrix_cell[src_y]
delete matrix_dst[0]; // int *matrix_total = new int[dst_y*dst_x]
delete matrix_dst; // int **matrix_row_col = new matrix_cell[dst_y]
// the overhead is matrix_src and matrix_dst which are arrays of row pointers
// the row pointers makes it convenient to address the cells as [rown][coln]
say I have a 3x4 array with integer elements, I want to pass this array to a function that then takes all of the elements and multiplies them by some integer 'b' then returns this new array, how would I go about it? this is what I have currently
#include <iostream>
#include <math.h>
using namespace std;
// my function for multiplying arrays by some integer b
int* multarray(int (*a)[4], int b)
{
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
*(*(a+i)+j) *= b;
}
}
return *a;
}
int main()
{
// creating an array to test, values go from 1-12
int arr [3][4];
int k = 1;
for (int i = 0; i < 3; i++)
{
for (int j = 0; j < 4; j++)
{
arr[i][j] = k;
k++;
}
}
// trying to setup new 'array' as a product of the test array
int *newarray;
newarray = multarray(arr,3);
// printing values (works with *(newarray+i) only)
for (int i = 0; i < 3; i++)
{
for (int j=0; j<4; j++)
{
cout << *(*(newarray+i)+j);
}
}
return 0;
}
this works if I don't include the j part when printing all my values but as it is now, tells me I have an error: invalid type argument of unary '*' (have 'int')
Your function is not returning a new array, it's modifying an existing array. So (assuming this is not a problem for you) you should just change the return type to void.
void multarray(int (*a)[4], int b)
{
...
}
Then
multarray(arr,3);
for (int i = 0; i < 3; i++)
{
for (int j=0; j<4; j++)
{
cout << *(*(arr+i)+j);
}
}
If you really do want a function that returns a new array, then that's a whole different (and much more complicated) problem . Apart from anything else it's, strictly speaking, impossible to return an array in C++.
This question already has answers here:
Returning multidimensional array from function
(7 answers)
Closed 9 years ago.
I want to use a two dimensional int array which is returned from a function
how should I define the function return value ?
I used int** but the compiler gave error:
int** tableCreator(){
int** table=new int[10][10];
for(int xxx=1;xxx<10;xxx++){
for(int yyy=1;yyy<10;yyy++){
table[xxx][yyy]=xxx*yyy;
}
}
return(table); //Here:cannot convert from 'int (*)[10]' to 'int **'
}
Try this:
#include <cstdio>
#include <cstdlib>
int** createTable(int rows, int columns){
int** table = new int*[rows];
for(int i = 0; i < rows; i++) {
table[i] = new int[columns];
for(int j = 0; j < columns; j++){ table[i][j] = (i+j); }// sample set value;
}
return table;
}
void freeTable(int** table, int rows){
if(table){
for(int i = 0; i < rows; i++){ if(table[i]){ delete[] table[i]; } }
delete[] table;
}
}
void printTable(int** table, int rows, int columns){
for(int i = 0; i < rows; i++){
for(int j = 0; j < columns; j++){
printf("(%d,%d) -> %d\n", i, j, table[i][j]);
}
}
}
int main(int argc, char** argv){
int** table = createTable(10, 10);
printTable(table, 10, 10);
freeTable(table, 10);
return 0;
}
You need the second loop to allocate a 2-d array in C and similar operation to free it. a two-D array is in essence an array of arrays so can be expressed as a pointer array. the loop initializes the arrays pointed to the pointers.
Clarifying as per conversation with #Eric Postpischil below: changed createTable to take row/column count for truly dynamic allocation.
int** table=new int[10][10];
this is wrong. you cannot allocate space for 2D dynamic array in this way in C/C++.
Meanwhile, you declared array size as 10, so indices are from 0-9, but you are trying to assign values to index 10 in your nested for loops, which is not right too.
You may do the following for allocation:
int** table = new int*[10];
for (int i = 0; i < 10; ++i)
{
table[i] = new int[10];
}
Usually, the type used to point to an array is a pointer to an element of the array. Since a two-dimensional array of int is an array of array of int, you want a pointer to array of int. The C++ syntax for this type is int (*)[N], for some dimension N. This code demonstrates:
#define N 10
int (*tableCreator())[N]
{
int (*table)[N] = new int[N][N];
for (int i = 0; i < N; ++i)
for (int j = 0; j < N; ++j)
table[i][j] = i*j;
return table;
}
#include <iostream>
int main()
{
int (*t)[N] = tableCreator();
for (int i = 0; i < N; ++i)
{
for (int j = 0; j < N; ++j)
std::cout << t[i][j] << ' ';
std::cout << '\n';
}
delete [] t;
return 0;
}
I. Arrays are not pointers.
II. Why not vector<vector<int> >?
III. If not, then:
typedef int Int10Array[10];
Int10Array *arr = new Int10Array[10];
IV. Why write past the bounds? Do you want explicit nasal demons?
for(int xxx = 0; xxx < 10; xxx++)
^^^ ^^^^
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;
}
there is a topic about this subject which is working with arrays but I can't make it work with matrices.
(Topic: C++ array size dependent on function parameter causes compile errors)
In summary:
long rows, columns;
cin >> rows >> columns;
char *a = new char [rows];
compiles great in visual studio, but:
char **a = new char[rows][columns];
or
char *a[] = new char[rows][columns];
or
char *a[] = new char[rows][columns]();
or
char **a = new char[rows][columns]();
don't compile at all.
Any help? Thank you
The array-new operator only allocates 1-dimensional arrays. There are different solutions, depending on what sort of array structure you want. For dimensions only known at runtime, you can either create an array of arrays:
char **a = new char*[rows];
for (int i = 0; i < rows; ++i) {
a[i] = new char[columns];
}
or an array of elements with an associated array of pointers to the first element of each row (requiring just two hits to the memory allocator):
char *a = new char[rows*columns];
char **a = new char*[rows];
for (int i = 0; i < rows; ++i) {
a[i] = a + i*columns;
}
Either one will let you access matrix elements via a[row][column].
An alternate solution is to just use the one-dimensional array and generate indexes by hand:
char *a = new char[rows*columns];
...
a[columns*row + column]
This is probably faster than the double-indirection required in the first two solutions.
You could of course wrap this in a class to preserve a semblance of 2D indexing syntax:
class MatrixWrapper {
...
char& operator()(int row, int column) { return a_[columns*row + column]; }
...
};
...
a(row, column)
A n-dimensional array can not be directly allocated as you are trying to. Here is a way to do it.
int main(){
unsigned int **p;
unsigned int rows = 10;
unsigned int cols = 20;
p = new unsigned int* [rows];
for(size_t row = 0; row < rows; row++){
p[row] = new unsigned int [cols];
}
for(size_t row = 0; row < rows; row++){
delete [] p[row];
}
delete [] p;
}
If you're going to use c-arrays in c++ (instead of std::vector), you're stuck doing something like this:
long rows = 0;
long columns = 0;
cin >> rows >> columns;
// declaration
long** a = new long* [rows];
for(long i = 0; i < rows; ++i)
{
a[i] = new long[cols];
}
// initialization
for(long j = 0; j < rows; ++j)
{
for(long i = 0; i < rows; i++)
{
a[i][j] = 0;
}
}
// delete sub-arrays
for(long i = 0; i < rows; ++i)
{
delete[] a[i];
}
// delete array
delete[] a;