Zyre
Zyre

Reputation: 149

C++ error on delete[] after iterating through pointer

Environment: Windows 7 pro x64, Microsoft Visual Studio 2015 Enterprise, Version 14.0.25424.00 Update 3

int testFunction()
{
    std::string _orig = "[188 80% (1/2)O:152]";
    std::string _orig2 = "[999 99% (1/1)O:999]";

    char *orig = NULL;
    char *orig2 = NULL;

    orig = new char[_orig.length() + 1];
    strcpy(orig, _orig.c_str());

    orig2 = new char[_orig2.length() + 1];
    strcpy(orig2, _orig2.c_str());

    *orig++;
    *orig2++;

    int a = atoi(orig);
    int b = atoi(orig2);

    delete[] orig;
    delete[] orig2;

    return 0;
}

Running the above code crashes with the "_CrtIsValidHeapPointer(block)" error.

If I don't iterate (*orig++ and *orig2++), then no issues.

So my question is, how can I iterate through the pointers and then when I'm done doing what I need to do with them, delete[] them correctly?

Upvotes: 0

Views: 496

Answers (4)

AnatolyS
AnatolyS

Reputation: 4319

Avoid to use raw pointers. Your code can be simpler:

std::string orig = "[188 80% (1/2)O:152]";
std::string orig2 = "[999 99% (1/1)O:999]";

int a = atoi(orig.c_str() + 1);
int b = atoi(orig2.c_str() + 1);

Your mistake is that you try to delete the shifted pointers instead of the original pointers. As the result heap manager gets wrong allocated block information usually put before the allocated pointer and you got heap corruption.

Upvotes: 2

jonas_toth
jonas_toth

Reputation: 872

You did not delete the pointers you allocated!

delete must be called on the original memory address returned by new. Since you did orig++, you cant delete the address being pointed at!

Iterating can be done with an index, and using array subscription to dereference:

orig[i] = 'a';

Which is the same as doing this:

*(orig+i) = 'a';

Or you can get another pointer onto the same data, and modify this one.

char* pOrig = orig;
++pOrig;

Why did you write

*orig++; // why dereferencing?

Just ++ by itself would do the iteration.

Upvotes: 2

Zyre
Zyre

Reputation: 149

int testFunction()
{
    std::string _orig = "[188 80% (1/2)O:152]";

    int a = 0;
    for (std::string::iterator it = _orig.begin(); it != _orig.end(); ++it) 
    {
        if (isdigit((char)*it))
            a = (atoi(it._Ptr));
    }

    return 0;
}

I got it. Thanks for everyone who helped me come to this conclusion. Staying with std::string was in fact the best approach.

Upvotes: 0

eerorika
eerorika

Reputation: 238351

how can I iterate through the pointers and then when I'm done doing what I need to do with them, delete[] them correctly?

Create a copy of the pointer:

char* orig = new char[size];
char* i = orig;
*i++ = 'a';
delete orig;

A perhaps more common idiom is to dereference a temporary:

for(int i = 0; i < size - 1; i++)
    orig[i] = 'a';

I would love to [use std::string], but I need to use atoi(), which won't work on std::string

You are mistaken. atoi works with std::string just fine. Simply use std::string::c_str() just like you did with strcpy. There is absolutely no reason to allocate a block of memory with new.

Upvotes: 0

Related Questions