0

Right now I have a pointer set to a row in my 2D array. I want that pointer to stop pointing to that row, but I will be using the pointer later for something else. I just want to know how to unset the pointer after it is initialized and has pointed to a row.

double* tempRow;
tempRow = (double*) malloc(size * sizeof(double));
   ...
tempRow = NULL;

doesn't unlink the tempRow variable from the array row. Why not?

I wonder if I should be using C then instead. Will there be overhead when using a vector?

Stuart
  • 1,733
  • 4
  • 21
  • 34
  • 3
    So, which book are you learning from? This is terrible C++ code, to be blunt, and covered by any [introductory book](http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). You should pick one up so you can learn C++. The answer, of course, is to use `std::vector`. – GManNickG Oct 19 '10 at 06:14
  • 1
    -1 for "doesn't seem to work." – Chris Becke Oct 19 '10 at 07:31
  • doesn't seem to work was referring to the sentence above the code. ie Using the provided code "to unset the pointer after it is initialized and has pointed to a row ... doesn't seem to work." – Stuart Oct 19 '10 at 16:04
  • 2
    Okay, so what did happen? What did you do, and what, exactly, did you observe? What do you mean by "unlink", or "array row"? – David Thornley Oct 19 '10 at 16:08

5 Answers5

11

While you have written will set tempRow to NULL, it wont release the memory you have allocated. For that you need

free(tempRow);
tempRow = NULL;

However if you're using C++ as the tags suggest, you'd be better off using C++ new/delete

double* tempRow;
tempRow = new double[size];
   ...
delete [] tempRow;
tempRow = NULL;

you can even use the STL to handle your memory allocation for you.

std::vector<double> tempRow(size);
// You can access the data, in a similar way to an array
tempRow[5] = tempRow[4]+tempRow[3];

// If you really need to access the underlying pointer, (To pass to another 
// function for example) you can do this. Note that the pointer will be valid
// until the vector is destroyed or modified in certain ways that can cause the
// vector to reallocate its memory. So you can't use this to pass data to a 
// function that destroys or takes ownership of the passed in pointer.

fn_requiring_pointer( &temp[0] );

// The memory used in tempRow will get cleaned up automatically when the 
// object goes out of scope
//
// If I really need to free up the memory used in it early I can use a swap 
// hack. (iirc tempRow.clear() isn't guaranteed to release the memory)
std::vector<double>().swap(tempRow); // Unneeded in most cases.

Also trying to reuse the tempRow pointer for something unrelated is probably not necessary. Just create a new pointer with a different name. Reusing a variable form multiple different unrelated purposes can make code very hard to understand later.

Michael Anderson
  • 70,661
  • 7
  • 134
  • 187
6

I'm new at C++ as well, but a while ago, someone told me that using std::vector is a much safer approach to handling arrays of data.

  • Automatic re-allocation when adding more elements.
  • Iterators for use with stuff from #include <algorithm>.
  • Bounds-protection with .at(index) element access.
  • No messy pointer-tracking required.
  • C-array style access with operator[].
  • RAII.

You would declare a vector like this:

std::vector<double> tempRow(size);

tempRow[0] = 3.00;
tempRow[1] = 1.00;

// no need to use delete[] or free(), it will destruct itself
// and relinquish its resources automatically.
dreamlax
  • 93,976
  • 29
  • 161
  • 209
4

Doesn't seem to work?

That's the worst complaint and a solution providers's nightmare.

Do you mean you get a compilation error?

If yes, did you include <cstdio>? and using namespace std;

Chubsdad
  • 24,777
  • 4
  • 73
  • 129
4

The example you've shown should work.
Also if you've not freed the memory before making temRow NULL, you are leaking memory.

double* tempRow;
tempRow = (double*) malloc(size * sizeof(double));
   ...
free(tempRow);  // free the memory.
tempRow = NULL; // reset the pointer.
   ...
tempRow = &some_other_double_var; // reuse the pointer.
codaddict
  • 445,704
  • 82
  • 492
  • 529
  • I don't understand a lot about memory allocation. Doesn't free just unallocate the memory? Because that is not what I want. I wish to reuse the memory later in the program. I could free and set to NULL but then I'd have to reallocate the pointer every time I want to use it and I would rather avoid the overhead. Perhaps I misunderstand because in your example you are freeing, setting to NULL and then reusing it without a malloc call. Is this correct? – Stuart Oct 19 '10 at 16:13
  • @Stuart: When you set the pointer to `NULL` and you don't want to call free, you need to ensure that there is another way to get to the memory allocated. Say you might have another pointer pointing to it. In case if you don't have such a way, you are leaking memory, that is there is no way to get to that memory let aside freeing it. – codaddict Oct 19 '10 at 16:20
  • @Stuart: It's hard to understand what you're asking. `free()` deallocates the memory. If you want to keep the memory for later reuse, you need to keep a pointer to it. If you do `tempRow = NULL;` without `free(tempRow);` first, you've got the worst of both: unreusable memory that can't even be reallocated. BTW, you'd likely do better just `free`ing the memory and getting new memory later. The overhead is unlikely to be that bad, and you don't appear to be comfortable with memory allocation. – David Thornley Oct 19 '10 at 16:24
2

Doesn't work in what way? The normal way to "unset" a pointer in C++ is with:

tempRow = 0;

but what you have should be fine, assuming you've included the correct headers or otherwise have the correct definition for NULL.

As an aside, you should first call free() on that memory before losing the pointer, otherwise you'l have a memory leak (and this is assuming you have a good reason to use C-style malloc/free instead of the more kosher C++ new/delete).

paxdiablo
  • 854,327
  • 234
  • 1,573
  • 1,953