简体   繁体   English

遍历指针后在delete []上发生C ++错误

[英]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 环境:Windows 7 pro x64,Microsoft Visual Studio 2015 Enterprise,版本14.0.25424.00更新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. 运行上面的代码会因“ _CrtIsValidHeapPointer(block)”错误而崩溃。

If I don't iterate (*orig++ and *orig2++), then no issues. 如果我不进行迭代(* orig ++和* orig2 ++),则没有问题。

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 . 必须在new返回的原始内存地址上调用delete Since you did orig++ , you cant delete the address being pointed at! 由于您执行过orig++ ,因此无法delete所指向的地址!

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 我很想[使用std::string ],但是我需要使用atoi(),它在std :: string上不起作用

You are mistaken. 你误会了。 atoi works with std::string just fine. atoi可以与std::string一起使用。 Simply use std::string::c_str() just like you did with strcpy . 就像使用strcpy一样,只需使用std::string::c_str()即可。 There is absolutely no reason to allocate a block of memory with new . 绝对没有理由用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. 坚持使用std :: string实际上是最好的方法。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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