0

I've been posed with creating a dynamic 2D array in C++ without using new in C++. I have been trying for a while to make something work but I'm clueless as to what I'm supposed to do.

Edit: Sorry, should have been more specific. Just to be transparent, yes it is homework, and no I don't want it solved I just want to be pointed (no pun intended) in the right direction to code it myself.

The order, for reference, is as follow: Develop a console application to create a type int matrix of size m x n using pointers. The user must input the values for the size of the matrix from the keyboard and its contents must be randomly generated (1 - 100). Then, the transpose of the matrix must be calculated and shown (it's necessary to create classes).

We can't use new, nor vector, as we have to do it just via pointers with uni-dimensional arrays. So far I created a class that represent the "rows", and another class which represents the "columns". The columns go into the rows and the rows go into another class called matrix. That was the idea but was having trouble implementing it.

Max
  • 45
  • 5
  • 4
    What can you use? – Costantino Grana Oct 30 '19 at 17:49
  • 3
    I mean, can you use std::vector? – Costantino Grana Oct 30 '19 at 17:50
  • 2
    What about malloc? – Costantino Grana Oct 30 '19 at 17:50
  • Do you mean 'without heap allocations'? – HolyBlackCat Oct 30 '19 at 17:55
  • maybe make a class with a private `std::vector>` – tmlen Oct 30 '19 at 17:56
  • 1
    How about `std::make_unique`? [But seriously, here's the right1 way.](https://stackoverflow.com/a/2076668/4581301) 1Right for for a common pool of problems. – user4581301 Oct 30 '19 at 17:56
  • 2
    @tmlen That’s a *nested* array instead of a 2D array. I know that nested arrays are occasionally used to implement multi-dimensional arrays but they’re a *bad* implementation. – Konrad Rudolph Oct 30 '19 at 17:58
  • I expect this is a request to use a VLA even though they are illegal in standard `c++` [https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard](https://stackoverflow.com/questions/1887097/why-arent-variable-length-arrays-part-of-the-c-standard) – drescherjm Oct 30 '19 at 18:52
  • Do they give you a *maximum* size for those matrices? Those pointers they are talking about must point somewhere. – Bob__ Oct 30 '19 at 20:23
  • To my understanding, maximum size is input by the user – Max Oct 30 '19 at 20:29
  • @Max The size input by the user is the size of the array. The point is that is there a maximum for what the user is allowed to give. If you can assume a maximum, then you don't need to create the array dynamically. – eerorika Oct 30 '19 at 20:35
  • 1
    Confirm with your instructor whether or not you are not allowed to use `malloc`. It's old and [it's better suited to C programming](https://www.youtube.com/watch?v=YnWhqhNdYyk), but it is probably what the instructor intends for you to use. – user4581301 Oct 30 '19 at 20:52
  • @user4581301 we are allowed to use malloc. – Max Oct 30 '19 at 20:58
  • Then that's your last hope. [Read up on how it works](https://en.cppreference.com/w/cpp/memory/c/malloc) and try your best to avoid its many failings. – user4581301 Oct 30 '19 at 21:00
  • A recommendation though, make one big allocation of size MxN and perform the mapping between 1 and 2 dimensions with a helper function (`index = row * N + column`). One allocation is faster and easier to deal with than many. [Here is a good example](https://isocpp.org/wiki/faq/operator-overloading#matrix-subscript-op) the relevant differences to you are you need to replace calls to `new` with `malloc` and calls to `delete` with `free`. – user4581301 Oct 30 '19 at 21:05
  • Pay special attention to the copy constructor and the assignment operator because without them you'll almost certainly run afoul of [The Rule of Three](https://stackoverflow.com/questions/4172722/what-is-the-rule-of-three). – user4581301 Oct 30 '19 at 21:06
  • ```malloc``` did the trick! Thanks – Max Oct 30 '19 at 21:35
  • Thanks! I've corrected it. – Max Oct 30 '19 at 23:19

2 Answers2

4

new is the only way to create dynamic objects or arrays in standard C++. So, depending on how you interpret the task, it could be considered impossible.

If we assume that it is OK for you to call a standard function that internally calls new, then the problem is solvable. A commonly used way to create a dynamic array in C++ is to use std::vector. Elements of std::vector may not be arrays however, so a 2D dynamic array is not technically possible using it. One workaround is to wrap the array within a class, and use the class as element of the vector. There is a standard template for such array wrapper: std::array. An example of a vector of array wrappers:

std::vector<std::array<type_of_element, 10>> name_of_vector(number_of_arrays);

The elements of the arrays within the dynamic array managed by the vector will have effectively the same layout as a 2D array would.

eerorika
  • 232,697
  • 12
  • 197
  • 326
  • My bad, didn't specify I can't use other libraries, just good old ```int arr [ ]``` arrays – Max Oct 30 '19 at 20:14
  • 1
    @Max then your task is impossible in standard c++. `new` is the only way to create dynamic objects or arrays. – eerorika Oct 30 '19 at 20:15
2

malloc did the trick. Here is the code I used to test it. It was a bit convoluted to figure out how to write the matrix loop but once I got it down I realized how obvious it was.

Matriz::Matriz(int numFil, int numCol)
    :numFil(numFil), numCol(numCol)
{
    mat = (int *)malloc(numFil * numCol * sizeof (int));

    int c = 0;

    for(int i = 0; i < numFil; i++)
    {
        for(int j = 0; j < numCol; j++)
        {
            *(mat + i * numCol + j) = ++c;
        }
    }
}

void Matriz::printMat()
{
    for(int i = 0; i < numFil; i++)
    {
        for(int j = 0; j < numCol; j++)
        {
            std::cout << *(mat + i*numCol + j);
        }
         std::cout << std::endl;
    }
}
Max
  • 45
  • 5