0

I'm using c++ and I want to use two dimensional dynamic array. I tried this:

#include<iostream.h>
using namespace std;
void main(){
int const w=2;
int size;
cout<<"enter number of vertex:\n";
cin>>size;
int a[size][w];
for(int i=0; i<size; i++)
   for(int j=0; j<w; j++){
      cin>>a[i][j];
  }

}

but not worded. and I tried this:

int *a = new a[size][w];

instead of

int a[size][w];

but not worked!

could you help me plz.

thanks a lot.

1
  • I wish to help without Template or Vector or classes.. thanks Commented Jan 10, 2014 at 17:31

4 Answers 4

4

The correct approach here would be to encapsulate some of the standard containers, that will manage memory for you, inside a class that provides a good interface. The common approach there would be an overload of operator() taking two arguments that determine the row and column in the matrix.

That aside, what you are trying to create manually is an array of dynamic size of arrays of constant size 2. With the aid of typedef you can write that in a simple to understand manner:

const int w = 2;
typedef int array2int[w];
int size = some_dynamic_value();
array2int *p = new array2int[size];

Without the typedef, the syntax is a bit more convoluted, but doable:

int (*p)[w] = new int [size][w];

In both cases you would release memory with the same simple statement:

delete [] p;

The difference with the approaches doing double pointers (int **) is that the memory layout of the array is really that of an array of two dimensions, rather than a jump table into multiple separately allocated unidimensional arrays, providing better locality of data. The number of allocations is lower: one allocation vs. size + 1 allocations, reducing the memory fragmentation. It also reduces the potential from memory leaks (a single pointer is allocated, either you leak everything or you don't leak at all).

Sign up to request clarification or add additional context in comments.

4 Comments

Upvoted: Improving locality of reference, decreasing memory fragmentation, potentially reducing risk of memory leaks... This answer encompasses a lot.
It would be helpful if you explained why this works syntactically, step by step. This is definitely not a beginner-friendly way to do this, so please clarify.
@Keeler: The simple explanation is in the first block of code, it dynamically allocates an array of array2int objects, each element in the array is a statically sized (in this case size==2) array. The complexity is in attempting to parse the awkward syntax that is required to do it without a typedef, but that is just learning how to read declarations: p is a pointer to an (or array of) w-dimensional array of int. If you feel that something needs further explanation, please do ask. I do agree that this is not beginner-friendly (I already mentioned that I would not use this approach)
+1 from me. I like this approach. Did not know you could allocate like this.
2

For a dynamic sized array you must dynamically allocate it. Instead of

int *a = new a[size][w];

Use

int** a = new int*[size];
for(int i = 0; i < size; i++)
    a[i] = new int[w];

5 Comments

This calls new[] too many times. Only one of the dimensions is dynamic, so a single new [] (with the appropriate type) suffices.
@DavidRodríguez-dribeas I don't see what you mean, the use of new [] code is fine.
@Keeler: in the code above (second block) there are size + 1 allocations, where only one allocation is needed. This has different impacts: higher cost of allocating/deallocating, memory fragmentation, less locality of data.
You mean 1 allocation as in int* a = new int[size * w];? Your way allocates it all as a single, contiguous block; @dornhege's example isn't guaranteed to use contiguous memory, but it should still compile and run just fine. I agree, it may not be the most efficient, but it still works, which is my point. Plus, no pointer arithmetic, which is scary to newbies.
@Keeler: I just wrote an answer, as no one else seemed to want to take that approach. I really meant int (*a)[w] = new int[size][w];. Single allocation, memory footprint and efficiency similar to that intended in the original non-compliant code, same syntax to access the elements (no need for arithmetic). Although in production code I would write a thin wrapper around std::vector<int> with operator()(int r, int c) doing integral arithmetic (no pointer arithmetic) to index a r * width + c.
1

OP is saying he wants to create a 2 dimensional array where one dimension is already known and constant and the other dimension is dynamic.. Not sure if I got it right but here goes:

int main() {
    const int w = 2;

    int size = 10;

    int* arr[w];

    for (int i = 0; i < w; ++i)
        arr[i] = new int[size];


    //do whatever with arr..
    //std::cout<<arr[0][0];

    for (int i = 0; i < w; ++i)
        for (int j = 0; j < size; ++j)
            std::cout<<arr[i][j];


    for (int i = 0; i < w; ++i)
        delete[] arr[i];

    return 0;
}

Comments

1

You can not do that in c++, please read about dynamic memory allocation

the code below should work

int* twoDimentionalArray = new [size*w]

3 Comments

that's not a two-dimensional array, that's a simple array. twoDimentionalArray + 1 will point to the second item of the array but not to the second row as expected.
It can be done the way you propose, but it needs additional arithmetic
@ichramm Yea, it does require more arithmatic work, but it's worth it as the memory is kept in one block and you only ask for memory once. You also don't need to call many deletes. In this way you can also access the data with one indirection, instead of two, so i think that it's worth it.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.