error C2440: '=' : cannot convert from 'int *' to 'int **' - c++

#ifndef _grid_h
#define _grid_h
#include<string>
using namespace std;
template<typename T>
class grid{
T** main;
public:
grid<T>(){}
grid<T>(int col, int row){
main = new T[col]; //<-this line gives me error C2440:
//'=' : cannot convert from 'int *' to 'int **'
for(int i =0;i<col;i++)
main[i]=new T[row];
}
};
#endif
I want to create my own version of the Grid class. Basically I want to save the information in a 2 dimensional array of T. I think this is the most efficient way to do it. Now How can I get around this error?

It would need to be
main = new T*[col];
Because main is an array of pointers to T. But there are better ways to create a two-dimensional array, for example
std::vector<std::vector<T>> main(col, std::vector<T>(row));

Allocate an array of correct type: use main = new T*[col]; instead of main = new T[col];.

The answer is in your last code line:
main[i]=new T[row];
For that to work, main[i] needs to be a pointer. But you tried to create main as a new T[col] - an array of Ts. It needs to be an array of pointers-to-T.
main = new T*[col]; // Create an array of pointers

Related

C++: Type of multidimensional array with `variable` size

I can run this
int a = 5;
auto foo = new int [a][4][4];
But when I try this:
int a = 5;
int * foo[4][4];
foo = new int [a][4][4];
I get the error
error: incompatible types in assignment of ‘int (*)[4][4]’ to ‘int* [4][4]’
Question
What type do I have to specify for foo?
Edit:
The goal is to have one single chunk of memory, not an array of pointers.
The error message is a little confusing because it does not state the variable name.
This works:
int a = 5;
int (*foo)[4][4];
foo = new int [a][4][4];
As #john correctly identified:
You're confused between a 2D array of pointers (that's what you wrote) and a pointer to a 2D array (that's what you want).
So what's the difference between pointer to an array and array of pointers. The correct syntax to define a pointer to an array (what you tried to do):
data_type (*var_name)[array_size];
But this defines an array of pointers (what you actually did):
data_type *var_name[array_size];
#OP in your own answer you already found out what the correct type should be – a pointer to an array int (*foo)[4][4], but I thought a little more explanation is also helpful.

Wrong use of typedef of typedef(?)

I have problem with code from book:
const int SQUARE_ARRAY_SIZE = 4;
const int SQUARE_INFO_SIZE = 4;
typedef Square SquareArray[SQUARE_ARRAY_SIZE];
typedef SquareArray SquareInfo[SQUARE_INFO_SIZE];
SquareArray RedGeneric = { Square(0, 0), Square(0, 1),
Square(1, 1), Square(1, 0) };
SquareInfo RedInfo = { &RedGeneric, &RedGeneric, \\problem here
&RedGeneric, &RedGeneric };
It yells:
error C2440: 'initializing' : cannot convert from 'SquareArray (*)' to 'Square'
IntelliSense: no suitable constructor exists to convert from "SquareArray *" to "Square"
As I understand SquareInfo stands for array of SquareArray but it seems like vs2013 wants to break it to Squares and as result
SquareInfo m_squareInfo; ...
SquareArray* pSquareArray = m_squareInfo[m_iDirection];
yells:
IntelliSense: a value of type "const Square *" cannot be used to initialize an entity of type "SquareArray *"
Book is from 2008 and I don't know if it worked back then or there is error from beginning. As for q please tell me what's really wrong and how to make it work.
I'm fairly sure that the book meant to write
typedef SquareArray* SquareInfo[SQUARE_INFO_SIZE];
// ^
i.e., SquareInfo is an array of pointers to SquareArrays, rather than an array of SquareArrays. This is consistent with initializations using &RedGeneric and SquareArray* pSquareArray = m_squareInfo[m_iDirection];.
Looks like your book has a typo on that line
typedef SquareArray SquareInfo[SQUARE_INFO_SIZE];
When I make this to be a pointer
typedef SquareArray* SquareInfo[SQUARE_INFO_SIZE];
// ^
the code compiles fine.

Assigning array - "cannot convert from double* to double[]"

I've been doing this problem for a good few hours now so the answer might be obvious and I'm missing it, but I keep getting the errors:
C2440: '=' : cannot convert from 'double *' to 'double[7]'
IntelliSense: expression must be a modifiable lvalue
Heres the code having the issues:
#include <iostream>
#include <string>
#include <iomanip>
using namespace std;
class SnowData
{
private:
int dates[7];
double inches[7];
string monthName;
int startdate;
public:
SnowData(string _monthName, int _startdate, double* _inches)
{
inches = _inches;
monthName = _monthName;
startdate = _startdate;
}
I just need to get the _inches from my constructor into my inches array and I can finally finish this problem.
Just like #chris said, you cannot assign arrays. However, you can assign individual elements (provided they have an appropriate = operator).
for(int i = 0; i < 7; ++i) {
inches[i] = _inches[i];
}
This iterates through inches and assigns every element with a corresponding on in _inches.
Warning: undefined behavior is _inches size is less than 7.
If you must use a low-level array, then you'll probably want to copy the elements individually from the input array to the member array. You can't just assign the pointer value to the array.
You cannot assign an array that way. You should add the numbers of "_inches" pointed by _inches in your method, and use memcopy that way :
memcpy(inches, _inches, _inches_count * sizeof(double));
And do not forget to check that _inches_count is smaller than 7 !

Allocating memory specified by a reference variable for nested arrays?

I am supposed to implement a function
void foo(string** &grid);
Where I populate the given reference with a freshly allocated array or array of strings, I'd imagine.
I've done things like
void foo(string** &grid) {
grid = new string[4][4];
}
But I get this error:
error: cannot convert 'std::string (*)[4] {aka std::basic_string<char> (*)[4]}' to 'std::string** {aka std::basic_string<char>**} in assignment
Hm.
I see what this error is trying to tell me, but what is my fundamental misunderstanding here, and how would I go about doing what I want to do?
Thank you
new string[4][4] creates a pointer to string[4], not a pointer to pointer to string. The closest you can get is something like this:
grid = new string*[4];
for (int i = 0; i < 4; i++) {
grid[i] = new string[4];
}
But note that the 16 strings created in the process might not all be stored contiguously in memory.

Passing and returning 2d arrays in C++

So I am new to c++ and I have written this piece of c++ code.
#include <iostream>
using namespace std;
int** mat_mult(int mat1[2][2], int mat2[2][2]){
int mat3[2][2] = {{0,0},{0,0}};
for(int i(0);i<2;i++){
for(int j(0);j<2;j++){
for(int k(0);k<2;k++){
mat3[i][j] += mat1[i][k]*mat2[k][j];
}
}
}
return mat3;
}
int** mat_pow(int mat[2][2], int n){
int mat1[2][2] = {{1,0},{0,1}};
while(n){
if(n%2==1){
mat1 = mat_mult(mat, mat1);
}
mat = mat_mult(mat,mat);
n >>= 1;
}
return mat1;
}
int specialFib(int n){
int mat[2][2] = {{0,1},{2,1}};
mat = mat_pow(mat,n);
return (mat[0][0]*2 + mat[0][1]);
}
int main(){
cout << specialFib(3) << endl;
return 0;
}
But compiling this gives me this error,
prog.cpp: In function 'int** mat_mult(int (*)[2], int (*)[2])':
prog.cpp:13: error: cannot convert 'int (*)[2]' to 'int**' in return
prog.cpp: In function 'int** mat_pow(int (*)[2], int)':
prog.cpp:20: error: incompatible types in assignment of 'int**' to 'int [2][2]'
prog.cpp:22: error: cannot convert 'int**' to 'int (*)[2]' in assignment
prog.cpp:25: error: cannot convert 'int (*)[2]' to 'int**' in return
prog.cpp: In function 'int specialFib(int)':
prog.cpp:30: error: incompatible types in assignment of 'int**' to 'int [2][2]'
I tried to find any solution, but no luck. :(
int **mat3 = {{0,0},{0,0}};
This makes mat3 a pointer to a pointer to an integer. You can initialize it to any pointer to a pointer to an integer you want. But {{0,0},{0,0}} is an array, not a pointer to a pointer to an integer.
Perhaps you want:
int mat3[2][2] ...
If you want to dynamically allocate your 2d array then your code should look like that:
int** mat3 = new int*[2];
for(int i = 0; i < 2; ++i)
mat3[i] = new int[2];
and then deallocation:
for(int i = 0; i < 2; ++i) {
delete [] mat3[i];
}
delete [] mat3;
also you must manually initialize its values
as in other answers, I would never use such dynamic arrays, but vector of vectors
You tagged this question C++ so use C++!
You can either use std::array<std::array<int,Xsize>, Ysixe>> if you know both sizes at compile time or std::vector<std::vector<int>> otherwise.
In C++, arrays are very special collection facilities. You should definitely read more about standard container classes and then write everything new from scratch -- Trust me, it will save time! :)
Objects of standard container classes can be returned from a function in the same easy way as primitive types (like int or double).
std::vector<std::vector<int> > GetInts()
{
// ...
return v;
}
Your problem will simply disappear.
Pointers and arrays imply low-level memory management; that is certainly not beginners stuff!