0

I want to create a non-rectangular matrix that can output something like this:

0 0 0 0 0 0
0 0 0
0 0 0 0 
0 0 0 0 0 0

using 2-dimensional pointers.

I have a 1D pointer that points to an array which stores the size of each row : {6, 3, 4, 6, -1}.

-1 is a flag that will stop the while loop.

#include <iostream>
using namespace std;


template<class T>
T** allocate(int* sizes) {

    T** twod; // 2-dimensional pointer

    while (*sizes != -1) { // the loop will stop when *sizes hit -1
        *twod = new T[*sizes];
        twod++;
    }

    return twod;
}

int main() {
    int array[] = {6,3, 4, 6, -1};
    int* sizes = array; // 1-D pointer to the array which stores the size of each row

    int** twod = allocate<int>(sizes);

    for(int i = 0; i < 5; i++){
        for(int j = 0; j < *(sizes+i); j++){
            twod[i][j] = 0;
            cout << twod[i][j] << " ";
        }
        cout << endl;
    }
}

The program doesn't output anything. Can you guys help me point out the problem here? I think it might have to do with the while loop.

Thanks a lot!

(This is an assignment of mine regarding the use of pointers. I have to use pointers to output something above. I know using static arrays are much easier)

  • 1
    In your `allocate` function you have a pointer `twod`, but nowhere do you make it actually point anywhere. That means the dereference will be invalid and lead to [*undefined behavior*](https://en.wikipedia.org/wiki/Undefined_behavior). – Some programmer dude Sep 29 '18 at 02:31
  • 1
    Not to mention the fact that in your `allocate` function you do `twod++` which means the pointer you return will be one *beyond* the end of any memory you make `twod` point to. You simply lose the original pointer (once you properly initialize it). – Some programmer dude Sep 29 '18 at 02:32
  • Lastly, whenever you think about "dynamic arrays", you next thought should *always* be [`std::vector`](http://en.cppreference.com/w/cpp/container/vector). – Some programmer dude Sep 29 '18 at 02:33
  • 1
    Oh and just to nitpick: A matrix is a fixed-size data structure with MxN elements. You're trying to create a [*jagged array*](https://en.wikipedia.org/wiki/Jagged_array). – Some programmer dude Sep 29 '18 at 02:35
  • @someprogrammerdude: Really appreciate the comments, but can you help me improve that line? I rewrote: T** twod = new int*[4] but there are no outputs still. And we are not allowed to use the vector library – Pemi Nguyen Sep 29 '18 at 02:35
  • 2
    `for (size_t i = 0; sizes[i] != -1; ++i) { twod[i] = new T[sizes[i]]; }` – Some programmer dude Sep 29 '18 at 02:37
  • This is an awful assignment for understanding pointers given that pointers are *completely* unnecessary for this problem. – David G Sep 29 '18 at 02:39
  • And a few quick *last* lastly points: In the `main` function you don't need the pointer `sizes`, you can use `array` directly. Also, your loops to initialize and print the zeroes is wrong. I suggest you [learn how to debug your programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). And perhaps [get a few good books](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list/388282#388282) to read through. – Some programmer dude Sep 29 '18 at 02:40
  • @someprogrammerdude: got it! Thank you! Can you explain why using the while loop is not efficient? – Pemi Nguyen Sep 29 '18 at 02:41
  • @someprogrammerdude: I put a note down under saying that the pointer "sizes" is a part of the assignment to understand pointer. Using static array can be more convenient tho – Pemi Nguyen Sep 29 '18 at 02:42
  • @PemiNguyen [Learn from a working example](https://stackoverflow.com/questions/21943621/how-to-create-a-contiguous-2d-array-in-c) – PaulMcKenzie Sep 29 '18 at 02:48
  • That's an awful way to do it. I'd use a vector of vectors. Anyways, create an array of pointers, where each pointers is a dynamically allocated array representing each row. –  Sep 29 '18 at 03:14
  • @blade -- Creating a vector of vectors is easy, but not cache friendly. Creating each row dynamically, if you know the number of columns is a fixed size, is not a good way to do this, even though it is the way that is taught in books and school. If the array is `M x N`, The memory will become fragmented, plus the overhead of having to call `new[]/delete[]` `M + 1` times. It's better to allocate the entire pool of memory once (or twice for the pointers), and just point the array of pointers in the right spot in the pool. – PaulMcKenzie Sep 29 '18 at 09:12

1 Answers1

0

The output is not as what you expect just because your allocate() function is not logical. You can try it:

#include <iostream>
using namespace std;

template<class T>
T** allocate(int* sizes) 
{

   T** twod; // 2-dimensional pointer
   for(int i = 0;(*sizes)!=-1;i++)
   {
      twod[i] = new T[*sizes];
      sizes++;
   }
   return twod;
}
TaQuangTu
  • 2,155
  • 2
  • 16
  • 30