2016-07-30 64 views
0

环境后:视窗7亲64,微软的Visual Studio 2015企业版本14.0.25424.00更新3C++上删除错误[]通过指针迭代

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; 
} 

运行上面代码崩溃与“_CrtIsValidHeapPointer(块)“错误。

如果我不迭代(* orig ++和* orig2 ++),那么没有问题。

所以我的问题是,我怎样才能遍历指针,然后当我做完我需要做的与他们,删除[]他们正确?

+0

为什么要使用'char'指针?整个使用'std :: string'。 –

+0

我很想,但我需要使用atoi(),它不会在标准::字符串上工作 – Zyre

+2

(1)为什么你需要它?有C++等价物。 (2)你* *实际上可以将'std :: string'中的指针传递给'atoi'就好了:'atoi(str.c_str())'起作用。 –

回答

2

你没有删除你分配的指针!

delete必须在由new返回的原始存储器地址上调用。既然你做了orig++,你不能指定delete的地址!

迭代可以用指数来完成,并使用数组订阅取消引用:

orig[i] = 'a'; 

这是一样的这样做:

*(orig+i) = 'a'; 

或者你可以得到另一个指针到同一数据,并修改这一个。

char* pOrig = orig; 
++pOrig; 

你为什么写

*orig++; // why dereferencing? 

本身就++会做迭代。

+0

是的,这种方法很可能是您的第二个代码块,您可以在其中创建指针副本并遍历该指针,然后删除原始代码块。 – Zyre

+0

错误来自删除, 我眼中的指数更容易迭代,因为你总是现在在哪里你atm。 您的循环是否是真正的代码?或者你真的只是在那里一步? –

+0

作为另一个评论提到,使用std :: string(如果可能)。还有转换功能:http://www.cplusplus.com/reference/string/,例如用于字符串到整数转换的stoi –

0

我该如何迭代指针,然后当我完成我需要做的事情时,正确删除[]它们?

创建的指针的副本:

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

一个也许更常见的成语是取消引用一个临时的:

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

我很想[使用std::string ],但我需要使用atoi(),它不会在std :: string上工作

你错了。 atoi只适用于std::string。只需使用std::string::c_str(),就像您使用strcpy一样。绝对没有理由用new分配一块内存。

+0

是的,这也是我要去的方式,但不知道这是最好的方法。我很高兴你提到/确认了它。谢谢。 – Zyre

0
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; 
} 

我明白了。感谢帮助我得出这个结论的每个人。事实上,保持std :: string是最好的方法。

2

避免使用原始指针。您的代码可以更简单:

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); 

你的错误是,试图删除移动指针而不是原来的指针。由于堆管理器通常在分配的指针之前得到了错误的分配块信息,并且你得到了堆损坏。