Delete pointer to multidimensional array in class through another pointer - how?
Asked Answered
J

4

1

I have a pointer to a class, that have a pointer to a multidimensional array but I can't seem to delete it from memory when I need to or set it to NULL.

#define X 10
#define Y 10

struct TestClass
{
public:
       int      *pArray[X][Y];
};


// different tries, none working:

delete Pointer_To_TestClass->pArray[0][0];
delete[] Pointer_To_TestClass->pArray[0][0]

// or by simply:

Pointer_To_TestClass->pArray[0][0] = NULL;

I know the array has data because I can see the results on screen. Also check if it's NULL already, then doesn't try to delete it.

Since I want to delete a pointer in another pointer - is this a special circumstance that works differently? Like it deletes the first pointer holding the other pointer instead of the pointer inside the pointer (pArray is the second pointer, Pointer_To_Testclass is the first pointer)

UPDATE/EXPLANATION

I want to be able to delete pArray[0][0] while pArray[0][1] still exists and if [0][0] doesn't exist it should be equal to NULL. Most because I want to access this array by [X][Y] values for easy access. If [0][0] is a pointer, it should be NULL when deleted so I can check if it is NULL.

Anyone has any ideas?

Jahnke answered 17/8, 2012 at 16:45 Comment(21)
Pointer to multidimensional array, eh? int *pArray[1][2]; yields declare pArray as array 1 of array 2 of pointer to int on cdecl.Yogini
I use a class instead of "int" but it was easier to add.Jahnke
That has nothing to do with it, though. It's a multidimensional array of pointers, not a pointer to a multidimensional array.Yogini
Something tells me you need to rethink your code. There's bound to be a better way.Demetra
Please consider using std::vector for arrays in C++. A pointer to a jagged 2D array would then be declared as std::vector<std::vector<int> >*.Simasimah
I have alot of objects onscreen with X and Y coordinates, in a grid system. Aren't pointers to these objects preferably - considering they're suppose to be deleted at some point? So, my class has a Multidimensional array of a "class" in it, and I get a pointer to the class containing the 2d array.Jahnke
I would recommend following the rule of zero instead. That said, the answer to "how do I delete this thing?" depends on the answer to "how did I allocate this thing?", which was not included in the question.Lesialesion
Why can't I use Object[X][Y] when I need exactly how many objects there are going to be? and I need those positions and those positions only during one runtime. And to have pointers in Object[X][Y]-> isn't that preferable?Jahnke
@Deukalion, for your situation, why not a vector of Object, where each has an x and y inside it? Use erase to erase one object from the vector.Yogini
I want to easily be able to delete objects that are not needed within the "array", so I can check if there's something on the "grid". And I frequently will delete objects from this grid so pointer I believe is preferable.Jahnke
Exactly. Store just the objects you need in a std::vector (which can change its size), add the objects in when you need to using push_back, and remove the objects when you need to using erase.Yogini
Say every 60 second I will delete at least 25% of the objects in the array, as far as I know a vector allocates more memory?Jahnke
@Deukalion, It's implementation-defined how much extra memory it allocates, but it won't be too much, and it will be transparent to you.Yogini
I already changed from vector<Object> (where the object then had a int X, int Y field/property in it) to Object[X][Y] where it instead only have the data needed.Jahnke
Then you should probably change the title of the question, since you talk about a pointer to an array.Levite
std::vector will resize itself accordingly, sometimes doubling its previously allocated space. It will not shrink itself unless you explicitly do so.Simasimah
My question is still, why can I create a pointer: Object *Object[X][Y] and store data in it (with pointers, through Object[X][Y] = new Object() but not delete the data since it IS a pointer.)Jahnke
@Jahnke How is Pointer_To_TestClass declared? Is it a TestClass object, or a pointer to a TestClass object? That might be messing up your syntax in Pointer_To_TestClass->Acrimony
Yes. As I said earlier I believe that's the answer but no one listened. In WINMAIN I create an object of TestClass, pass it as a pointer to a method that handles Drawing of the Window, inside that method I either add a new pointer to the array or delete it, therefor the method handling the drawing of the window only has a pointer to TestClass to work with so the array is is a pointer inside another pointer. I believed, as I stated earlier that I get access violation because it gets confused and deletes the pointer to the object I'm working with (TestClass) instead of (element in Objects[X][Y])Jahnke
Most important thing is that I can delete the object and that I can check if an object with coordinates [X][Y] is NULL or not, easiest done with pointers. With a vector or similiar I have to loop to that position, over and over and over and over again if done frequently.Jahnke
@Jahnke Please update your question with extra information and an updated question. It doesn't show well in the comments.Drum
S
6

If you want a 2D array of pointers to <whatever>, create a class to handle that, then put an instance of it in your TestClass. As far as how to do that, I'd generally use something on this order:

template <class T>
class matrix2d {
    std::vector<T> data;
    size_t cols;
    size_t rows;
public:
    matrix2d(size_t y, size_t x) : cols(x), rows(y), data(x*y) {}
    T &operator()(size_t y, size_t x) { 
        assert(x<=cols);
        assert(y<=rows);
        return data[y*cols+x];
    }
    T operator()(size_t y, size_t x) const { 
        assert(x<=cols);
        assert(y<=rows);
        return data[y*cols+x];
    }
};

class TestClass { 
    matrix2d<int *> array(10, 10);
public:
    // ...
};

Given that you're storing pointers, however, you might want to consider using Boost ptr_vector instead of std::vector.

Seften answered 17/8, 2012 at 16:59 Comment(2)
You are kinda re-inventing boost::multi_array here.Fabulous
The coordinates are backwards. Incrementing the second coordinate should be the small jump, incrementing the first coordinate should be the larger jump. As it is, a for(i) for(j) nested loop needs to say mat(j, i) to get the right memory traversal.Sequacious
G
2
#define X 10
#define Y 10

struct TestClass
{
public:
  TestClass()
  {
    // Must initialize pArray to point to real int's otherwise pArray
    // will have bogus pointers.
    for (size_t y = 0; y < Y; ++y)
      {
    for (size_t x = 0; x < X; ++x)
      {
        pArray[x][y] = new int;
      }
      }
  }

  int      *pArray[X][Y];
};

int main()
{
  TestClass *Pointer_To_TestClass = new TestClass;
  delete Pointer_To_TestClass->pArray[0][0];
  Pointer_To_TestClass->pArray[0][0] = 0;
  return 0;
}
Goodish answered 17/8, 2012 at 17:54 Comment(5)
But I don't want to reset the whole array (pArray) I want to reset the values inside the array [x][y] so I can check if the value is NULL or not. If NULL will skip, else will do something with the data. If I have a normal array the value isn't NULL. I might need pArray[0][0] but not pArray[0][1] for example, therefor pArray[0][1] should be deletable while pArray[0][0] isn't deleted.Jahnke
...and the object pArray is not of "ints" it's of objects (class created) so I need to be able to set it as NULL.Jahnke
...which I can't with this method.Jahnke
@Jahnke I'm sorry my assumption that you wanted a 2 dimensional array of ints was incorrect. Are you initializing pArray? At first when it is created it will have garbage, it will have whatever data is left over on the stack or heap. If it isn't initialized, you will likely get errors when you try to delete it.Goodish
I changed the code in my comment above to show one way that pArray could be initialized.Goodish
G
0

If you've dynamically created an array, then delete it with delete[]. You have to give delete[] a pointer to the start of the array, however, not an element of the array!

If you want the elements to be deletable, then they have to be dynamically allocated separately.

So you have to have a multi-dimensional array of pointers;

int *(*pArray)[X][Y];

Then dynamically assign each one, which yes is a pain.

It is interesting, however, that you are even attempting to do this, why do you want to delete single elements?

Gab answered 17/8, 2012 at 17:1 Comment(14)
I have a grid of a set size, depending on my program it should render stuff on each of these X and Y coordinates but if not it should not even be stored in memory because it isn't needed. Or I might want to delete a big chuck of it in one go and also be able to check what fields in Grid is occupied and which is not.Jahnke
Simply put, once I'm done with the object[X][Y] it's not needed anymore.Jahnke
Then maybe when the 'object' class should have a de-activated mode? One that deletes most of the information ready to be activated again.Gab
You didn't write how to delete the objects once I've set them. I want the elemens not needed not to be "present" and when I'm done with it I want to delete just an object in that array. I guess the pointer to the object that holds the pointer to this array is deleted when I try this.Jahnke
If you did it as I said earlier, then use delete pArray[i][j]; as you did before to delete.Gab
I want to be able to access "if (Objects[X][Y] == NULL) // do something) and then also when it's not NULL, be able to delete it. I want [X][Y] system because it's the most flexible. When deleting an object in an vector I have to restart to vector.begin()+position again because next position has changed. It's annoying.Jahnke
That thing in the answer is a pointer to a multidimensional array, not a multidimensional array of pointers.Lesialesion
I can't delete[][] MainClass->pArray[i][j], "unrecoverable block scoping error". Remember that I access the array through another pointer.Jahnke
"Pointer to multidimensional array", which is what my title said.Jahnke
Just tried: delete[][] *(*PointerToClass->PointerToArray)[x][y]; and: syntax error: ''Jahnke
I can't figure out where to place PointerToClass in *(*pArray)[x][y]. because I can't just access pArray because PointerToClass object has it.Jahnke
After I declared my array as you've written in your answer above I can't access it as I use to and I can't call the "delete" (delete[][] to be exact) on the array because I have no idea how to access the array with the "Pointer to the class that holds the pointer to the array" which has not been included in the example above.Jahnke
There's no such thing as delete[][], only delete[] and delete.Gab
Well, neither works. And I still can't set pArray[x][y] = NULL; or delete them.Jahnke
A
0

Depends on your allocation of pArray[i][j]. If it's something like pArray[i][j] = new int; then call delete Pointer_To_TestClass->pArray[0][0];. If it's something like pArray[i][j] = new int[10] then use your second option, delete[] Pointer_To_TestClass->pArray[0][0];. I'd also highly recommend immediately following the delete with setting it to NULL and proceeding it with the check for NULL.

The third one did not compile for me delete[][] Pointer_To_TestClass->pArray[0][0]; I got the error

Line 34: error: expected primary-expression before '[' token compilation terminated due to -Wfatal-errors.

Also, I'd highly recommend having those deletes in the destructor. Other places may be fine as well.

You may find the typedef of int* to be helpful for readability understanding you have a two-dimensional array of int*.

Acrimony answered 17/8, 2012 at 17:32 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.