views:

67

answers:

7

Hi there,

I want to have a condition in my program that finds if there is NO value in an array. Usually the array will be filed with 4 values. On a rare occasion it is filled with 6. I want to use an if statement that says, if the exampleArray[5] is not equal to null, do this

Something like...

eg. if(!array[5]->Equals(null){ //Do stuff }

Problem is I can't use 0, because there is a good chance the int will be 0 and I don't want the code(//do stuff) to execute in that case.. The foundations of the program revolve around a 2D array and a very common a location contains a 0 int

as I'm reading on the net im finding that 0 is null for an integer.

How can I find null without using 0?

+1  A: 

What you can do is instead of storing integers directly, you could make a small class that stored an integer and an initialization flag. So when the object is created, it's uninitialized. When it's assigned it becomes initialized with a value. That would be the best way, you could also just fill the array with some value that you're pretty darn sure won't come up like static const int NOT_INITIALIZED = -99999999 or something and test against that.

bshields
+5  A: 

Instead of using an array you can use std::vector which has a size() method. This makes writing the if condition trivial.

Naveen
yes, I'll keep it in mind for the future, but I'm 4 months into a project and need to do this... I did actually just figure out a way around this...But I'm interested now, just for knowledge's sack... seems stupid that 0 int would be used as null when 0 is a number used in array locations
John McMohan
If you can't use a vector or some other sized container, then why not just define another variable to keep track of the number of valid elements in the array?
Avalanchis
@Jimbob - std::vector can be a drop-in replacement for C arrays, so I don't really think it matters that you are 4 months into the project or whatnot. The only thing you have to be careful about is using the size-altering methods (instead of just assigning into the result of `operator[]`) when you want to change the logcial length of your vector. In fact, I'd bet Naveen here could make the required changes to your code in an afternoon.
T.E.D.
A: 

You have a few choices.

You could store 'int*' in the array (making the array itself int**). This has the added overhead of you having to do extra memory management, but makes it possible to unambiguously store NULL. I don't suggest this.

A better idea would be to break out the STL. std::vector would be perfect, I think. You can change the size of it dynamically instead of having to store sentinel values (or NULL).

Donnie
A: 

Talking about an array with 4 or 5 elements, I'm guessing you don't have a memory size problem. Why not reserve one location in the array for a counter? That would be a bit of a "poor man's Vector" solution. Ideally, one would use location 0 in the array for the counter, but if you have a lot of code that believes in indexes starting at 0, you could put your counter at the opposite end, say at location 6 or 7. That element of the array would contain the number of items held in the array.

Declaring a "not initialized" value and searching the array for that is feasible but a rather inelegant solution. For one thing, it costs longer to loop and search than to simply look at a single value.

Ideally, that counter shouldn't even be in your array; it should be in a separate variable (we're once again approaching the Vector class suggested by others). But putting it in the array will probably make for a simpler change. Just look out for the possibility of storing more-than-expected values in the array and stomping over your counter!

Carl Smotricz
+1  A: 

Yes, signal values can be hard to come up with. There's nothing special about NULL when you're talking about a non-pointer. It's just as hard to find a date that means "no date" or a string that means "no string" but is not an empty string. That's why using signal values is rare outside of database programming, where the popularity of positive integers for ids and keys makes -1 a handy signal value.

I see you as having three choices. One, store pointers in your array. A null pointer is way different from a pointer to an integer with the value zero. But this has overhead (doubles the storage you need) and might mess with your head or the heads of others. Two, use your own class to represent this thing and have one member of the class hold whether there are 4 or 6 or whatever values, and use that member in your if statements. Three, use a readily available grows-itself-when-you-add-one container like std::vector and use its properties (eg size()) in your if statements. This has the disadvantage that you'll need to rewrite the code that accesses elements of the array. So I would vote for door #2.

Kate Gregory
A: 

OK. The first thing I want to make clear here is that C++ array's don't have a length. They may have an allocated size, but there is no way to figure out programattically what that is. By definition every element in a C++ array has a value. It may be garbage (if you haven't initialized it), but it is there and accessible. Heck, you can even access elements outside your array. Your OS may stop you, but C++ won't.

If you want arrays that have a logical size (that keep track of the amount of data "in" them), you have three real options:

  • Do it yourself with a sentinel value. Pick some value that will never legitimately appear in your array, and use that to indicate "end of data". If you do this, you have to be careful to declare (or allocate) an array big enough to hold all the data you may ever want, plus one more spot for the sentinel. You also have to be very careful about remembering to keep the sentinel updated, or you will get crashes galore. Figuring out the length requires a traversal of the entire array, so it can be slow (asuming you didn't mess something up, and it will terminate at all). This is the approach taken by C strings.
  • Do it yourself with a separate length variable. This will work great, as long as you can remember to keep the length up to date. If you mess this up, you will most likely just get subtle errors rather than spectacular crashes, but that has its drawbacks. Also, you have to pass the legth around with the array to all subroutines. The biggest problem though is that C++ pretty much will do this for you if you use the method below, so writing all the extra code to do it manually is kinda stupid.
  • Use std::vector instead of a dumb array. This gives you all of the advantages of an array, and all the advantages of a container, without all the work of keeping track of logical and allocated lengths. It will even go reallocate the array for you if you run out of room! The only real drawback here is that since it looks so much like an array, it is easy to forget that you have to use routines like .push_back() and .pop_back() to change its logical size.
T.E.D.
A: 

The fundamental issue is that C++ doesn't have a null value. There are null pointer values, but those aren't the same thing. There is also the null termination on a string, but again that's something different.

There's no way of specifying a null value in general that would work for C++, given its design philosophy. Either a null value has to be some sort of disallowed value, or there has to be some sort of external flag - in other words, excess memory that has to be referenced in order to use a variable. Neither is satisfactory for a low-level language that requires efficiency.

There are going to be more possible pointer values than the process can actually use itself, so there's generally no harm in requiring a specified bad value. It doesn't have to be all-bits-zero, although that's the most common case; the zero is just the name of the pointer. (Yes, I'm looking forward to nullptr.) Similarly, text encodings don't use the entire possible range of values for characters, so reserving one for something definitely not a character works well enough. That doesn't apply to numbers, or any other sort of data in which all values are valid.

David Thornley