0

When executing this function, an error message pops up saying Access Violation Reading Location pointing to line 58 in dbgdel.cpp. Why is this? I cannot seem to find out the problem in my code.

int parse140(string str_array[], int array_size, string str, int &i)
{   
int word_begin = 0;
int length = 0;

while(word_begin <= str.rfind(" ") && i < array_size)
{
word_begin = word_start(str, word_begin);   
length = word_length(str, word_begin);

if(length < 0)
    length = str.length() - word_begin;
if(i == array_size)
    break;

str_array[i]= str.substr(word_begin, length);
i++;
}   
return i;
}
  • Uninitialized stack variable. http://stackoverflow.com/questions/127386/in-visual-studio-c-what-are-the-memory-allocation-representations – drescherjm Dec 03 '13 at 01:57
  • Was str_array and i initialized? – drescherjm Dec 03 '13 at 02:02
  • does i need to be initialized in the main? The main function looks like: string str = "This will be the test string."; string str_array[array_size]; int i = 0; int x = 0; int a; a = parse140(str_array, array_size, str, x); – user3042929 Dec 03 '13 at 02:14

1 Answers1

2

You never change the conditional of your while loop.

Each time your loop circulates around it always find the last space in a string that never changes throughout the loop body. This causes you to find the same word repeatedly, each time appending it to the next slot in your array until you run out of slots. And since you never check the i index against array_size to stop the madness, you eventually overrun your array and straight into undefined behavior:

int parse140(string str_array[], int array_size, string str, int &i)
{
    int word_begin = 0;
    int length = 0;

    while(word_begin <= str.rfind(" ")) // str NEVER changes
    {
        word_begin = word_start(str, word_begin);

        //check if word_begin is less than 0.. break
        if(word_begin < 0)
            break;
        length = word_length(str, word_begin);

        if(length < 0)
            length = str.length() - word_begin;

        str_array[i]= str.substr(word_begin, length);

        i++;
    }

    return i;
}

Honestly, the fastest way to fix this is to not do it how you're doing it. Were I faced with this, I would do it like this, which you may find a little more .. brief:

#include <iostream>
#include <sstream>

int parse140(std::string str_array[], int array_size, std::string str, int &i)
{
    std::istringstream iss(str);
    for (i=0; i<array_size && (iss >> str_array[i]); ++i);
    return i;
}

Alternative Approach

Without using string streams, this is still fairly reasonable using the algorithms library, stripping all whitespace and only extracting words.

int parse140(string str_array[], int array_size, string str, int &i)
{
    std::string::iterator it = str.begin();
    for (i=0; i<array_size && it != str.end(); ++i)
    {
        // locate first non-whitspace character
        it = std::find_if_not(it, str.end(), is_space());
        if (it != str.end())
        {
            // find first whitespace or end-of-string
            std::string::iterator itEnd = std::find_if(it, str.end(), is_space());
            str_array[i].assign(it, itEnd);
            it = itEnd;
        }
    }
    return i;
}
WhozCraig
  • 65,258
  • 11
  • 75
  • 141
  • Im having trouble finding the right place to place the check for i being less than array_size. What seems most logical to me is to put it up inside the condition for the while statement.. adding && i < array_size) Then it will end up just printing out the first word a bunch of times. Having trouble moving it to the next word. – user3042929 Dec 03 '13 at 03:22
  • @user3042929 thats an issue with your implementation. If you're going to finish the implementation you started you need to ensure the loop breaks when `i == array_size` *and* you need to ensure your string `str` is properly updated to remove the "word" you just extracted. Thus the reason I simply chose to use a string-stream, which does all the white space skipping and content extraction for you. – WhozCraig Dec 03 '13 at 03:30
  • Was the code required to put the words in reverse order into the array? It seemed like the example was starting at the end. – drescherjm Dec 03 '13 at 04:06
  • Unfortunately the guidelines do no allow me to use string-stream. Which makes no sense because thats what people use in the real world correct? Frustrating teacher. Could you give me an example line of code on how to "dump" the previous word so it has space for the next one? – user3042929 Dec 03 '13 at 04:19
  • @user3042929 If you can't use string stream, then it is still possible with some iterator work, just more tedious. Are you at least allowed to use lambdas ? – WhozCraig Dec 03 '13 at 04:32
  • Yes. But I have other functions in this particular set of code that I need to use. Having trouble dumping the first word and moving onto the next, it prints the first word a bunch. I thought i++ would take care of that? – user3042929 Dec 03 '13 at 06:39
  • The problems you mentioned is due to the repetitious word-search you're doing on the *same string*. After you extract each word, you're making no changes to `str` to remove that word. thus on the next loop iteration it find the same word, again and again, until you fill up your array. You need to think about what you have to do to `str` to remove the word just found. It will likely be a `str = str.substr(...);` call, though without knowing the exact nature of your `word_begin()` and `word_length()` functions, filling in the blanks will elude me. Think about it for awhile, it will come to you. – WhozCraig Dec 03 '13 at 07:29