KalibiddJlddkO
KalibiddJlddkO

Reputation: 21

Using 2D array of pointers leads to error

I have something like the follow:

template<class T>
struct point{
   point* next = nullptr;
   T* data = nullptr;
}

template<class T>
class newClass
{
   point<T>*** points;

public:
   newClass()
   {
      points = new point<T>**[10];
      for (int i = 0; i < 10; i++)
          points[i] = new point<T>*[10];

      for (int i = 0; i < 10; i++)
          for(int j = 0; j < 10; j++)
             if(j != 9)
                points[i][j]->next = points[i][j+1]; //ERROR
   }
};

Can someone help me understand why this produces an error? I don't receive an error message, the program just crashes.

Upvotes: 0

Views: 57

Answers (3)

dspfnder
dspfnder

Reputation: 1123

You have too many pointer operators. The code below will work...

#include <iostream>

using namespace std;

template<class T>
struct point {
    point* next = nullptr;
    T* data = nullptr;
    T* operator->() {
        return data;
    }
};

template<class T>
class newClass
{
    point<T>** points;

public:
    newClass()
    {
        points = new point<T>*[10];
        for (int i = 0; i < 10; i++) {
            points[i] = new point<T>[10];
        }

        for (int i = 0; i < 10; i++) {
            for (int j = 0; j < 10; j++) {
                if (j != 9) {
                    points[i][j].next = points[i][j + 1].next; //ERROR
                }
            }
        }
    }
};

int main()
{
    newClass<int> nc;

    return 0;
}

Upvotes: 0

Vlad from Moscow
Vlad from Moscow

Reputation: 310930

The type of expression

points[i][j]

is point<T> *. This pointer was not initialized. It has indertermined value. At first you need to allocate an object that will be pointed to by this pointer. For example

points[i][j] = new point<t>();

Otherwise this

points[i][j]->next 

refers nowhere.

I think you mean the following

template<class T>
class newClass
{
   point<T> **points;

public:
   newClass()
   {
      points = new point<T>*[10];
      for (int i = 0; i < 10; i++)
          points[i] = new point<T>[10]();

      for (int i = 0; i < 9; i++)
                points[i]->next = points[i+1];
   }
};

Upvotes: 0

Some programmer dude
Some programmer dude

Reputation: 409166

When you do points[i][j]->next you dereference an uninitialized pointer which leads to undefined behavior.

Drop one level of indirection and do

points[i][j].next = &points[i][j+1];

Or, do an extra allocation loop to initialize that last pointer too.


For a different way, you don't need to use pointers at all here, especially since your allocations are all of a fixed size, which means you can use fixed arrays, or even better, std::array:

std::array<std::array<point<T>, 10>, 10> points;

Upvotes: 3

Related Questions