Access violation reading location 0x00701000

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');
Last edited on
for (; p != nullptr; ++p)

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.
How can I resolve this error and prevent it from looping forever?
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.
Last edited on
So like this? if (*p == 0){ break; }
for (; *p != 0; ++p)
Thank you for your assistance. That seems to do the trick. Could you please help me understand why?
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.

Read about pointers: http://www.cplusplus.com/articles/EN3hAqkS/
Last edited on
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.
Last edited on
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++?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
#include <iostream>
#include <algorithm>

// int count_x( char* p, char x)
// std::size_t is the appropriate integral type for this
// see: http://en.cppreference.com/w/cpp/types/size_t
// C++ has a strong notion of immutability or const-ness
// see: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#Rconst-ref
//      https://isocpp.org/wiki/faq/const-correctness
std::size_t count( const char* p, char x )
{
    if( p == nullptr || x == 0 ) return 0 ;

    std::size_t cnt = 0 ;
    for( ; *p != 0 ; ++p ) if( *p == x ) ++cnt ;
    return cnt ;
}

// http://www.stroustrup.com/C++11FAQ.html#auto
// auto for the return type indicates that the return type
// will be deduced from the operand of its return statement
// http://en.cppreference.com/w/cpp/language/auto
auto count_v2( const std::string& str, char x )
{
    // http://en.cppreference.com/w/cpp/iterator/begin
    // http://en.cppreference.com/w/cpp/string/basic_string/begin
    // http://en.cppreference.com/w/cpp/algorithm/count
    return std::count( std::cbegin(str), std::cend(str), x ) ;
}

int main()
{
    const char cstr[] = "CppCoreGuidelines: By default, pass pointers and references to const's" ;

    const auto cnt = count( cstr, 's' ) ; // array to pointer decay

    // implicit conversion to const std::string - std::string defines
    // a converting constructor which accepts a null-terminated character string
    const auto cnt2 = count_v2( cstr, 's' ) ;

    std::cout << cnt << " == " << cnt2 << '\n' ;
}

http://coliru.stacked-crooked.com/a/ccd75dacdd2fef83
Do you know by chance if they are any books that help .NET developers transition to C++?


Here's a tiny little bit on a site that you'll find very helpful in general

https://isocpp.org/wiki/faq/csharp-java
Last edited on
Topic archived. No new replies allowed.