Your main question seems to be why deleting a pointer doesn't set the pointed-to address to null. I'll answer this question, but also try to open your eyes to some more modern C++ styles towards the end of my answer.
In general, you're allowed to
delete
pointers that come from any expression, such as a function call. In that case, it's impossible to set the returned pointer to null:
Thing* getThingToDelete();
void main(){
delete getThingToDelete();
// how can delete set the returned pointer to null???
}
So if you own a pointer which is allowed to be null sometimes, it's good practice (but not required) to set that pointer to nullptr
after you delete
it, as a form of book-keeping. This is just something to get used to when dealing with pointers and manual memory allocation, as well as thinking rigorously about ownership, correctly using new
, delete
, new[]
, and delete[]
, checking for nullptr
, and keeping track of array sizes. Really, it's a lot to think about, and it quickly gets in the way of what you set out to do in the first place. It's for this reason that a lot of modern C++ features exist to hide all this noise and take care of all the minutiae without the programmer's conscious intervention. An example follows below.
Consider this modern makeover of your code:
#include <vector>
#include <string>
#include <iostream>
#include <algorithm>
struct DATA_STRUCT {
std::string Name;
int Value;
};
struct SOME_STRUCT {
// I'm not sure if SomeArray is supposed to be used as a string or array
// so here's both:
std::string SomeString;
std::vector<char> SomeCharArray;
// the need for VarCount is unclear, but if you want to get the number
// of elements in Var, you simply write:
// > Var.size()
std::vector<DATA_STRUCT> Var;
};
int main(int argc, char** argv){
SOME_STRUCT s;
// some example usage:
// is there anything in s?
bool hasAnyVars = !s.Var.empty();
// add a new value to s, with value=16 and name="Jeffrey"
s.Var.push_back({ "Jeffrey", 16 });
// how many items are in s now?
size_t numItems = s.Var.size();
// is there anyone named Helga?
bool foundHelga = std::find_if(s.Var.begin(), s.Var.end(), [](const auto& x){
return x.Name == "Helga";
}) != s.Var.end();
// print every thing in the list
for (const auto& x : s.Var){
std::cout << "Name=" << x.Name << ", value=" << x.Value << '\n';
}
// end of examples
return 1;
}
Notice that I didn't use any pointers at all. Additionally, this code is free of memory leaks, and I never had to think about manual allocation. As you can see, modern C++ allows your program to have much richer, clearer semantics than before, and a large number of common tasks can be done if only a couple lines of code. There's a number of possibly unfamiliar things appearing in my examples that I'll provide links to here:
string
- a super-simple, idiot-proof alternative to C-style strings
vector
- obviously you've seen this, but the docs show many useful member functions you might not know about
- iterators - generic pointer-like accessors into standard library containers, work very nicely with standard algorithms
find_if
and friends from the <algorithms>
library - convenient, generic search functions for any container
- lambda expressions - anonymous, local functions which can also refer to local variables
- the
auto
keyword - automatically deduces the type of a variable; can spare you lots of typing and maintenance work
- ranged
for
-loops - the shortest, simplest way to write a for
loop over all elements in a container
Also be aware that if you really need pointer semantics, such as having multiple references to an object or want to manage the lifetime of a polymorphic object simply, there is also:
unique_ptr
- a smart pointer that automatically deletes itself when you are done using it. Only ever has one owner.
shared_ptr
- a smart pointer that can have multiple references. Deletes itself when all places in your code are done using it.
I did leave your names largely unchanged, though it's uncommon nowadays to see code written in all capitals. It sometimes makes me worry that FORTRAN HAS RETURNED TO SHOUT AT ME but that's subjective of me, and it's really a matter of one's own preference.