tags:

views:

278

answers:

6

hi I want to do something like this:

int op(string s1, string s2){
    int x = s1.size();
    int y = s2.size();
    int matrix = new int[x][y]
    /* do stuff with matrix */
}

For some reason I get the following errors:

SuperString.cpp(69) : error C2540: non-constant expression as array bound
SuperString.cpp(69) : error C2440: 'initializing' : cannot convert from 'int (*)[1]' to 'int'
        This conversion requires a reinterpret_cast, a C-style cast or function-style cast
SuperString.cpp(71) : error C2109: subscript requires array or pointer type

Thanks!

+3  A: 

You need to declare the matrix var as int* matrix, as a dynamic array is declared as a pointer. But you can't do a 2d array in one new with both dimensions being variable. You can do a 1D array and do the indexing math on your own.
int* matrix = new int[x*y];
// Set element x1,y1 to 5
matrix[x1+y1*x] = 5;

Zanson
Ok. And then what?
Hamish Grubijan
It's 2d array in question, and `int*` won't work
billyswong
@Zanson: Read the question carefully.
Prasoon Saurav
@Zanson: "as an array is a pointer" is not correct. Array is an "array", it might be converted to a pointer type whenever required, for example while passing an array to a function, array in the calling function is converted to a pointer type as formal argument in the called function.
Prasoon Saurav
@Prasoon yeah I read the compiler warning and missed the 2d part when I first answered.
Zanson
+1  A: 

You cannot have a matrix of non-constant row size.

You may choose to have an "array of pointers to arrays" structure which can be indexed as pp[a][b] just as a matrix. You cannot allocate such a structure with a single new. You will have to build it manually within a buffer.

Pavel Radzivilovsky
+11  A: 

Here is a summary of how to build a 2d array in C++ using various techniques.

Static 2D Matrix:

const size_t N = 25; // the dimension of the matrix

int matrix[N][N]; // N must be known at compile-time.
// you can't change the size of N afterwards

for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
     matrix[i][j] = /* random value! */;
    }
}

Dynamic 2d Matrix:

const size_t N = 25; // the dimension of the matrix
int** matrix = new int*[N]; // each element is a pointer to an array.

for(size_t i = 0; i < N; ++i)
    matrix[i] = new int[N]; // build rows

for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
     matrix[i][j] = /* random value! */;
    }
}

// DON'T FORGET TO DELETE THE MATRIX!
for(size_t i = 0; i < N; ++i)
    delete matrix[i];

delete matrix;

Matrix using std::vector:

// Note: This has some additional overhead
// This overhead would be eliminated once C++0x becomes main-stream ;)
// I am talking about r-value references specifically.
typedef vector< vector<int> > Matrix;
typedef vector<int> Row;

const size_t N = 25; // the dimension of the matrix
Matrix matrix(N);

for(size_t i = 0; i < N; ++i)
{
    Row row(N);

    for(size_t j = 0; j < N; ++j)
    {
     row[j] = /* random value! */;
    }

    matrix.push_back(row); // push each row after you fill it
}

// Once you fill the matrix, you can use it like native arrays
for(size_t i = 0; i < N; ++i)
{
    for(size_t j = 0; j < N; ++j)
    {
     cout << matrix[i][j] << " ";
    }

    cout << endl;
}

3d matrix using boost::multi_array (taken from boost multi_array docs):

// Note that this is much more efficient than using std::vector!
int 
main () {
  // Create a 3D array that is 3 x 4 x 2
  typedef boost::multi_array<double, 3> array_type;
  typedef array_type::index index;
  array_type A(boost::extents[3][4][2]);

  // Assign values to the elements
  int values = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        A[i][j][k] = values++;

  // Verify values
  int verify = 0;
  for(index i = 0; i != 3; ++i) 
    for(index j = 0; j != 4; ++j)
      for(index k = 0; k != 2; ++k)
        assert(A[i][j][k] == verify++);

  return 0;
}
AraK
+1 for completeness :)
Prasoon Saurav
+2  A: 

Use boost::multi_array. See the doc and this question for details.

That will help you avoid a lot of errors.

Klaim
+2  A: 

If the size of matrix does not need to change through the function, you can declare the ints storing the string length as const. This allows you to create a multi-dimensional array that can vary in size for each function call, but retains a constant size for the duration of the function.

#include <iostream>
#include <string>

using namespace std;

int someFunc(string, string);

int someFunc(string s1, string s2)
{
    const int x = s1.length();
    const int y = s2.length();

    int matrix[x][y];
    int result=0;

    for(int i=0;i<x;i++)
     for(int j=0;j<y;j++)
      matrix[i][j]=i*j;

    for(int i=0;i<x;i++)
     for(int j=0;j<y;j++)
      result+=matrix[i][j];

    return result;
}

int main()
{
    string s1 = "fubar";
    string s2 = "somethingelse";

    cout<<someFunc(s1,s2)<<endl;
}

EDIT: On reading one of the other answers posted while I was writing mine, I suppose you should use const size_t instead of const int. Sorry, my C++ is just a little rusty.

Chinmay Kanchi
A: 

It's more like a syntax problem.

Last check in gcc 4.4, int matrix[x][y]; seems to work as expected. If your array don't need resizing in the middle of the function. You may try this syntax and see if it works in your compiler.

billyswong