0

I wanted to add a row to a previously dynamically allocated 2-D array but the complier gives an error that lvalue is required at the line where I am trying to allocate new memory to the new row.

#include<iostream>
//#include<stdlib.h>
using namespace std;

int main()
{
    int (*p)[2] = new (int [5][2]);
    for(int i =0; i<5; i++)
    {
        for(int j =0; j<2; j++)
        {
            p[i][j]= i;
        }
    }

//    p = (int **) realloc(void*, 12)
    int **l = (int **)p;
    (l+5) = new int[1][2];
    p[5][0] = 5;
    p[5][1] = 5;

    for(int i =0; i<=5; i++)
    {
        for(int j =0; j<2; j++)
        {
            cout<<p[i][j];
        }
    }

}
LihO
  • 41,190
  • 11
  • 99
  • 167
  • 2
    `int **l = (int **)p;` That's... awfuly wrong. A pointer to twodimensional array is not a pointer to pointer. There's a good reason for the error you got when you tried without the cast. – jrok Aug 28 '13 at 07:04
  • 1
    See [`std::vector`](http://en.cppreference.com/w/cpp/container/vector). – Some programmer dude Aug 28 '13 at 07:04
  • Although pointing out `std::vector` is perfectly right thing to do. This seems to be rather taken from a simple school assignment used for teaching arrays... – LihO Aug 28 '13 at 07:06
  • 1
    You cannot mix new and realloc (at least not portably). `std::vector` is the easy way to do this. – john Aug 28 '13 at 07:06
  • By the way, if you want to know the difference between an array-of-arrays (what a two-dimensional array is) and a pointer-to-pointer, see e.g. [this previous answer of mine](http://stackoverflow.com/a/18440456/440558). – Some programmer dude Aug 28 '13 at 07:10
  • That makes as much sense as `int x = 0; (x + 5) = 12;`. – molbdnilo Aug 28 '13 at 07:17

1 Answers1

0

Using C-style arrays in C++ code will yield ghastly code. It's hard to read, hard to understand and what's the worst: hard to maintain. The proper solution here seems to be using std::vector instead.

But in case you have a reason not to use std::vector (i.e. it's some kind of school assignment), what you could do is to replace the original array with the newly-constructed one. So you have a pointer of type int (*)[2]:

// create an array and initialize it:
int (*p)[2] = new (int [5][2]);
for(int i = 0; i < 5; i++)
    for(int j = 0; j < 2; j++)
        p[i][j]= (i+1) * (j+1);

now you can create a new array represented by a pointer of same type and reassign the original pointer (the fact that you're working with the continuous block of memory can be used here to copy elements):

int (*p2)[2] = new (int [6][2]);
memcpy(&p2[0][0], &p[0][0], sizeof(int) * 5 * 2);
delete[] p;                                           // don't forget to clean up
p = p2;

but now there's some uninitialized memory that might cause undefined behavior so:

// initialize new row:
for(int j = 0; j < 2; j++)
    p[5][j]= 6*(j+1);

and now you can print the values and destruct the newly-created array as well (which can be done using the pointer p2 but also using the pointer p still):

for(int i = 0; i < 6; i++)
    for(int j = 0; j < 2; j++)
        std::cout << p[i][j] << ' ';

delete[] p;

which prints 1 2 2 4 3 6 4 8 5 10 6 12 :)


PS: If you have problems with memcpy not being defined, try to #include <cstring>

LihO
  • 41,190
  • 11
  • 99
  • 167