2

I have allocated an array of object as:

int numPlwDistanceClimb = 5;
int numFl = 6;
GRBVar** t_gd = 0;
t_gd = new GRBVar* [numFl];
GRBVar* x = 0;
x = model.addVars(numFl, GRB_CONTINUOUS);
for (int k = 0; k < numFl; k++)
{
    t_gd[k] = model.addVars(numPlwDistanceClimb, GRB_CONTINUOUS);          
}

I delete the arrays as follows but it does not work.

 delete x;
 for (int i = 0; i < numFl; ++i)
 {
      delete t_gd[i];
 }
      delete [] t_gd;

Can anyone help me? Thank you in advance

  • 3
    Use `std::vector` instead and all your problems will be handled. – NathanOliver Aug 24 '17 at 12:54
  • you dont initialize every t_gd individually in this code – Serve Laurijssen Aug 24 '17 at 12:55
  • I don't see any code where you actually write into `t_gd`. If you call free on uninitialized pointers a crash is what you can expect. – ypnos Aug 24 '17 at 12:56
  • I initialize t_gd now. But it does not work !! – Thomas Edison Aug 24 '17 at 13:14
  • And what does `addVars` look like? Does it return a pointer that was created with `new`? – molbdnilo Aug 24 '17 at 13:15
  • @molbdnilo you can find addVars in here: http://www.gurobi.com/documentation/7.0/refman/py_model_addvars.html – Thomas Edison Aug 24 '17 at 13:17
  • Since it's a C API at heart, you probably want `free` instead of `delete` on those. – molbdnilo Aug 24 '17 at 13:21
  • @ThomasEdison -- *you can find addVars in here* -- Nowhere is it mentioned that a dynamically created object is returned that can be deallocated with `delete`. If it isn't mentioned, don't assume. An API that returns something that the client must deallocate would state as such. – PaulMcKenzie Aug 24 '17 at 13:30
  • @molbdnilo it works but does not free all variables. The leak reduces but not entirely. – Thomas Edison Aug 24 '17 at 13:31
  • 1
    @ThomasEdison *it works but does not free all variables* -- So did the API state that those addresses are allocated using `malloc`, `calloc`, or `realloc`? I think you're using the API incorrectly and overcomplicated your program using pointers. I am assuming that the authors of the C++ interface would properly implement the objects being returned in that there is no need for you to be manually releasing memory. The `addVars` function returns an object -- why not just use `std::vector t_gd(numF);` and fill the vector with the return value of `addVars`? – PaulMcKenzie Aug 24 '17 at 13:41
  • What exactly is `model.addVars` returning? Your code expects return a (modified) new GRBVar() – stefan bachert Aug 24 '17 at 13:47
  • I wrongly assumed that the C++ API was a thin C wrapper. A closer look at the C++ API overview yields this: "For example, `GRBModel::addVars` returns an array of `GRBVar` objects. It is the user's responsibility to free the returned array (using `delete[]`)." So you're missing the `[]`. – molbdnilo Aug 24 '17 at 13:49
  • @molbdnilo it does not work and worse than using free variable – Thomas Edison Aug 24 '17 at 14:00

2 Answers2

2

I have allocated an array of object as:

No you have allocated array of pointers to objects. Which means you have to allocate every pointer in that array if you want to use it properly, otherwise attempt to use them would cause undefined behavior.

GRBVar** t_gd = new GRBVar* [numFl];

for (int n = 0; n < numFl; n++)
{
    t_gd[i] = new GRBVar;
    // Or set them to nullptr
}

Also if you need array of pointers in C++, you could use std::vector

std::vector<GRBVar *> t_gd;

Where you dont have to allocate, free resources and you have way more possibilities.

Also you can use smart pointers

std::vector< std::unique_ptr< GRBVar > > t_gd;
kocica
  • 6,172
  • 2
  • 11
  • 34
1

You must at least put every element of t_gc to NULL, otherwise the array contains random values and when you delete those it will crash

GRBVar** t_gd = 0;
t_gd = new GRBVar* [numFl];

for (int i = 0; i < numFl; i++)
{
  t_gd[i] = NULL;
}
Serve Laurijssen
  • 7,989
  • 4
  • 30
  • 69