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;
Related
I have a vector of integers that I should make into a 2d array. The row and column size of the new 2d array are given by user and contain all the integers from previous vector. The 2d array should be of type const int* const*. How do I do this in c++?
Try something like this:
std::vector<int> nums;
// fill nums as needed...
int rows, cols;
std::cin >> rows >> cols;
if ((rows * cols) > nums.size())
// error
int** arr = new int*[rows];
for (int row = 0; row < rows; ++row) {
arr[row] = new int[cols];
for (int col = 0; col < cols; ++col) {
arr[row][col] = nums[(row*cols)+col];
}
}
// use arr as needed...
for (int row = 0; row < rows; ++row) {
delete[] arr[row];
}
delete[] arr;
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?
int **C = new int*[rows];
for(int i = 0; i < rows; i++){
C[i] = new int[cols];
for(int j = 0; j < cols; j++){
C[i][j] = 0;
}
}
I'm creating dynamic 2-D array, but can we somehow initialize the array with 0's in all the entries without using inner loop?
If you use std::vector instead, it would simply be
std::vector<std::vector<int>> C(rows, std::vector<int>(cols));
You can do it with value initialization
int **C = new int*[rows]();
for(int i = 0; i < rows; i++)
{
C[i] = new int[cols]();
}
However a std::vector would be nicer (because of memory management).
One option is to use the std::fill function:
int **C = new int*[rows];
for(int i = 0; i < rows; i++)
{
C[i] = new int[cols];
std::fill(C[i], C[i] + cols, 0);
}
using namespace std::placeholders;
std::for_each(C, C + rows, std::bind(std::fill_n<int*, std::size_t, int>, _1, cols, 0));
Or if reused often:
auto fill_row = [] (int i) { return [=] (int* r) { std::fill_n(r, cols, i); }; };
std::for_each(C, C + rows, fill_row(0));
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 am currently using the following code to get the current row and column of an element in a 2D int array:
const int num_rows = 5;
const int num_columns = 7;
int a[num_rows][num_columns];
int *p = &a[2][4];
int row = (p - &a[0][0]) / num_columns;
int col = (p - &a[row][0]);
This works fine but now I need to change the code to take the number of rows and columns as a parameter. As far as I know, this means I need to create the 2D array dynamically:
int** ary = new int*[sizeX];
for(int i = 0; i < sizeX; ++i)
ary[i] = new int[sizeY];
If I create the 2D array this way, the above code to find the row/column breaks. What can I do?
int *ary = new int [sizeX * sizeY]; // allocate memory for the 2d array
for(int i = 0; i < sizeX; ++I)
for(j = 0; j < sizeY; ++j)
ary[i * sizeY + j] = 0;
// to get the value of collumn c and row r: use ary[c * sizeY + r];
int row = (p - &a[0][0]) / num_columns;
int col = (p - &a[row][0]);
It's a very good idea to stay way from pointer arithmetic. Don't do this! You are essentially subtracting the pointer and divide that number by num_columns, and that number will be random.
If you want to get the row/column of an element, search the array one element at a time.
for(int row=0; row<num_rows; ++row) {
for(int column=0; column<num_columns; ++column) {
if (a[row][column] == element) {
// we got it!
}
}
}