a pointer that is null is one way.
if you are tracking it's size on the side in a variable, size==0 is a way
you can't just tell what is in a dynamic array, because it is byte-soup. You asked the OS for 1000000 bytes in a pile. It gives them to you. They are full of bits, more or less at random. You change some of those bits. How does it know which ones you changed and which are still random garbage? It can't do that efficiently, its too much to keep track of. You keep track of it yourself if you want to know, so that people who don't need to know this are not slowed down by under the hood stuff they do not need.
-- this is why vectors/containers exist. This is the best way to deal with it.
-- doing it yourself is usually just growing the back end, eg array[index++] = values in a loop, index is tracking what you have used so far... another way is to have an array of objects and one of the object's properties is whether it is used or not, default to not used, and bam...the array can tell you which locations are used or not.
By empty, I mean it has no values in its cells. The question said that I should check if the dynamic array is not null or empty. I can check null but I wonder how am I supposed to check if the dynamic array is empty.
it is declared like
string* array = new string[5];
let's say I didn't input any variable in this dynamic array. Is there anyway C++ can tell me that I didn't input anything before sorting for instance?
As jonnin said (with a lot of words): you must track that yourself.
There are two general methods.
• Using sentinel values
• Keeping count
For c-strings and arrays of pointers, a sentinel will work. For example:
1 2 3 4 5 6 7 8
// c-string
constchar* s = "Hello world!"; // same as = { 'H', 'e', ... , 'd', '!', '\0' };
// find the length
constchar* p = s;
while (*p) ++p;
length = p - s;
1 2 3 4 5 6 7 8 9 10 11 12 13
// array of pointers
string* strings[] =
{
new string{ "Hello" },
new string{ "world!" },
nullptr
};
// find the length
string* p = strings;
while (*p) ++p;
length = p - strings;
If that looks confusing, it is because it is pointer arithmetic. You could use a counter too:
1 2 3 4 5 6
constchar* s = "Hello world!";
int n = 0;
while (s[n]) n++;
length = n;
int values[ MAX_VALUES ];
int nvalues = 0;
// I currently have zero values in the array -- so says nvalues
std::cout << nvalues << "\n";
values[nvalues++] = 12;
values[nvalues++] = 31;
values[nvalues++] = -7;
// I currently have three values in the array -- so says nvalues
std::cout << nvalues << "\n";
nvalues -= 1;
// I now have just two value in the array.
// Yes, -7 is still there, but we are not counting it -- so say nvalues
std::cout << nvalues << "\n";
// Let us print all the values counted in the array
for (int n = 0; n < nvalues; n++)
std::cout << values[n] << " ";
std::cout << "\n";
BTW, there is not typically any need to keep a pointer to a std::string. Treat the std::string as any other automatic value and let the string class track its own memory for you:
I should add that a dynamic array works no differently. You first must ASK for the maximum number of cells you need, then track how many are actually used:
1 2 3 4 5 6 7
int max_values = 0;
int* values = newint[ max_values = 100 ]; // ask for an array of 100 values
int nvalues = 0; // currently using none of them
values[nvalues++] = -7; // now we are using one of them
...
Don’t forget to clean up after yourself when using pointers:
1 2
delete [] values;
max_values = nvalues = 0;
Arrays of pointers require additional cleanup, of course:
1 2 3
for (int n = 0; n < nstrings; n++)
delete strings[n];
...