Take the 2-minute tour ×

I've written a simple string tokenizing program using pointers for a recent school project. However, I'm having trouble with my StringTokenizer::Next() method, which, when called, is supposed to return a pointer to the first letter of the next word in the char array. I get no compile-time errors, but I get a runtime error which states:

Unhandled exception at 0x012c240f in Project 5.exe: 0xC0000005: Access violation reading location 0x002b0000.

The program currently tokenizes the char array, but then stops and this error pops up. I have a feeling it has to do with the NULL checking I'm doing in my Next() method.

So how can I fix this?

Also, if you notice anything I could do more efficiently or with better practice, please let me know.



#pragma once

class StringTokenizer
StringTokenizer(char* const, char);
char* Next(void);
char* pStart;
char* pNextWord;
char delim;


#include "stringtokenizer.h"
#include <iostream>
using namespace std;

pStart = NULL;
pNextWord = NULL;
delim = 'n';

StringTokenizer::StringTokenizer(char* const pArray, char d)
pStart = pArray;
delim = d;

char* StringTokenizer::Next(void)
pNextWord = pStart;
if (pStart == NULL) { return NULL; }

while (*pStart != delim) // access violation error here

if (pStart == NULL) { return NULL; }

*pStart = '\0'; // sometimes the access violation error occurs here

return pNextWord;

delete pStart;
delete pNextWord;


// The PrintHeader function prints out my
// student info in header form
// Parameters - none
// Pre-conditions - none
// Post-conditions - none
// Returns - void
void PrintHeader();

int main ( )
const int CHAR_ARRAY_CAPACITY = 128;

// create a place to hold the user's input
// and a char pointer to use with the next( ) function
char* nextWord;


cout << "\nString Tokenizer Project";
cout << "\nyour name\n\n";
cout << "Enter in a short string of words:";
cin.getline ( words, CHAR_ARRAY_CAPCITY_MINUS_ONE );

// create a tokenizer object, pass in the char array
// and a space character for the delimiter
StringTokenizer tk( words, ' ' );

// this loop will display the tokens
while ( ( nextWord = tk.Next ( ) ) != NULL )
    cout << nextWord << endl;

return 0;


Okay, I've got the program working fine now, as long as the delimiter is a space. But if I pass it a `/' as a delim, it comes up with the access violation error again. Any ideas?

Function that works with spaces:

char* StringTokenizer::Next(void)
pNextWord = pStart;

if (*pStart == '\0') { return NULL; }

while (*pStart != delim)

if (*pStart = '\0') { return NULL; }

*pStart = '\0';

return pNextWord;
share|improve this question

4 Answers 4

up vote 1 down vote accepted

This answer is provided based on the edited question and various comments/observations in other answers...

First, what are the possible states for pStart when Next() is called?

  1. pStart is NULL (default constructor or otherwise set to NULL)
  2. *pStart is '\0' (empty string at end of string)
  3. *pStart is delim (empty string at an adjacent delimiter)
  4. *pStart is anything else (non-empty-string token)

At this point we only need to worry about the first option. Therefore, I would use the original "if" check here:

if (pStart == NULL) { return NULL; }

Why don't we need to worry about cases 2 or 3 yet? You probably want to treat adjacent delimiters as having an empty-string token between them, including at the start and end of the string. (If not, adjust to taste.) The while loop will handle that for us, provided you also add the '\0' check (needed regardless):

while (*pStart != delim && *pStart != '\0')

After the while loop is where you need to be careful. What are the possible states now?

  1. *pStart is '\0' (token ends at end of string)
  2. *pStart is delim (token ends at next delimiter)

Note that pStart itself cannot be NULL here.

You need to return pNextWord (current token) for both of these conditions so you don't drop the last token (i.e., when *pStart is '\0'). The code handles case 2 correctly but not case 1 (original code dangerously incremented pStart past '\0', the new code returned NULL). In addition, it is important to reset pStart for case 1 correctly, such that the next call to Next() returns NULL. I'll leave the exact code as an exercise to reader, since it is homework after all ;)

It's a good exercise to outline the possible states of data throughout a function in order to determine the correct action for each state, similar to formally defining base cases vs. recursive cases for recursive functions.

Finally, I noticed you have delete calls on both pStart and pNextWord in your destructor. First, to delete arrays, you need to use delete [] ptr; (i.e., array delete). Second, you wouldn't delete both pStart and pNextWord because pNextWord points into the pStart array. Third, by the end, pStart no longer points to the start of the memory, so you would need a separate member to store the original start for the delete [] call. Lastly, these arrays are allocated on the stack and not the heap (i.e., using char var[], not char* var = new char[]), and therefore they shouldn't be deleted. Therefore, you should simply use an empty destructor.

Another useful tip is to count the number of new and delete calls; there should be the same number of each. In this case, you have zero new calls, and two delete calls, indicating a serious issue. If it was the opposite, it would indicate a memory leak.

share|improve this answer
Thanks, this was really, really helpful! –  Alex Feb 8 '10 at 6:24

Inside ::Next you need to check for the delim character, but you also need to check for the end of the buffer, (which I'm guessing is indicated by a \0).

while (*pStart != '\0' && *pStart != delim) // access violation error here

And I think that these tests in ::Next

if (pStart == NULL) { return NULL; }

Should be this instead.


That is, you should be checking for a Nul character, not a null pointer. Its not clear whether you intend for these tests to detect an uninitialized pStart pointer, or the end of the buffer.

share|improve this answer
Note that he sets the pointers to NULL in the no-arg constructor. –  Anon. Feb 8 '10 at 3:31
@Anon: yes, but he uses the other constructor, so the NULL test could be intended as bullet-proofing, or maybe not. –  John Knoeller Feb 8 '10 at 3:35
should I just get rid of my NULL checking then? Is it really pointless? –  Alex Feb 8 '10 at 3:47
Ok, now my program works, but if I pass it a different delimiter, it terminates with an access violation again. Weird. –  Alex Feb 8 '10 at 3:57
@Alex: NULL checking is not pointless, but in this case it was more important to check for the end of the string, and it wasn't clear if you mean for the null check to be the end of string check. –  John Knoeller Feb 8 '10 at 6:37

An access violation (or "segmentation fault" on some OSes) means you've attempted to read or write to a position in memory that you never allocated.

Consider the while loop in Next():


Let's say the string is "blah\0". Note that I've included the terminating null. Now, ask yourself: how does that loop know to stop when it reaches the end of the string?

More importantly: what happens with *pStart if the loop fails to stop at the end of the string?

share|improve this answer

An access violation usually means a bad pointer.

In this case, the most likely cause is running out of string before you find your delimiter.

share|improve this answer
what would be the best way to add error checking for this in my program? –  Alex Feb 8 '10 at 3:22
While you're iterating through your string, as well as checking for the delimiter, check for the terminating null which means the end of the string. If you find it, stop there and return the string. –  Anon. Feb 8 '10 at 3:23

Your Answer


