I am a C# developer by trade who has recently taken a job in C++ and I am trying to spin up. I have been reading the book a Tour around C++ and trying to test out a method for counting instances of a char in a char array. I am using Visual Studio 2013 for my IDE and when I attempt to run the below code, I get the following error: First-chance exception at 0x001D5563 in MyCppTestApp.exe: 0xC0000005: Access violation reading location 0x00701000.
Method Definition:
1 2 3 4 5 6 7 8 9 10 11
int count_x(char* p, char x)
// count the number of occurrences of x in p[]
// p is assumed to point to a zero-terminated array of char (or to nothing)
{
if (p == nullptr) return 0;
int count = 0;
for (; p != nullptr; ++p)
if (*p == x)
++count;
return count;
}
Method Call:
1 2 3 4
TestClass t;
char a[5] = "Josh"; // Notice the '6' that accounts for '\0' terminator
char* p = a; // Array decays into a pointer
int count = t.count_x(p, 'o');
p will never equal nullptr (or zero), so this will loop forever and eventually you'll be trying to use p when it's pointing into memory that isn't yours and the OS will stop you. Which is what's happening.
You need to stop the loop when the char being pointed to equals zero.
You can get the value of the char being pointed to with *p
As an aside, use braces for the body of your for loops. Use braces for the body of your if blocks. Beyond that, once you've finished learning about a char array for the purpose of education, never use a char array when you could use a string.
Your original code didn't work because you were testing that the pointer wasn't a nullptr.
The pointer began the for loop pointing to a char, so not a nullptr. All you ever did after that to the pointer was increment it. So it would never become a nullptr, so the loop would never end.
Your intent was to examine every char in an array, and stop when you had examined every char. The char array was "null terminated". This means that there is a zero value marking the end of the chars.
The pointer began in a state of pointing to the first char. ++p increments the pointer and made it point at the next char. So each ++p causes the pointer to be pointing at each subsequent char. Eventually, ++p makes the pointer point at the zero value after the last char. By checking the value of what the pointer is pointing at, you can know when it is pointing at the zero value and thus know when to stop.
Your original code didn't stop at that final zero, and kept going forever.
Thank you so much for taking the time to explain that for me. The critical piece I was missing was the "null terminated" explanation. Everything seems crystal clear now though. Thank you again so much for your assistance.
As a final note, be aware that marking the end of the data you care about in an array with a zero is done for you only in a small range of situations, and is something you should only rely on if you've double-checked that whatever made the array did that. Basically, it's done by some c-string related functions. It is not standard practice to use zero in an array to mark the end of data that you care about.
In C++, if you need a string type, use a std::string or other such fully featured C++ class.
Thank you again for your words of advice. That example came form the Tour C++ book that I am reading trying to spin up. Do you know by chance if they are any books that help .NET developers transition to C++?