简体   繁体   中英

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?

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.

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.

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 .

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM