C++ 在动态二维数组中检测到堆损坏
尝试使用delete释放内存时出现堆损坏错误 这是密码C++ 在动态二维数组中检测到堆损坏,c++,data-structures,memory-management,C++,Data Structures,Memory Management,尝试使用delete释放内存时出现堆损坏错误 这是密码 char** split(char* inputstr, char delim, int& count){ char** ostr=NULL; int numStr = 0; int i=0,j,index=0; while(inputstr[i]){ if(inputstr[i++]==delim) numStr++; } if(inputstr[i-1]!=delim) numStr
char** split(char* inputstr, char delim, int& count){
char** ostr=NULL;
int numStr = 0;
int i=0,j,index=0;
while(inputstr[i]){
if(inputstr[i++]==delim)
numStr++;
}
if(inputstr[i-1]!=delim)
numStr++;
count= numStr;
ostr = new char*[numStr];
i=0;
while(inputstr[i])
{
j=i;
while(inputstr[j] && inputstr[j] != delim)
j++;
ostr[index] = new char[j-i+1];
//istr[j] = 0;
strncpy(ostr[index], inputstr+i,j-i);
ostr[index++][j-i]=0;
i=j+1;
}
return ostr;
}
for(int i=0,countStr;i<_numComp;i++){
char** _str = split(str[1+i],':',countStr);
message.lastTransList.cmpName[i] = new char[strlen(_str[0])+1];
strcpy(message.lastTransList.cmpName[i],_str[0]);
message.lastTransList.price[i] = atof(_str[1]);
for(int i=0; i<countStr;i++)
{
delete[] _str[i]; //this is working fine
_str[i] = 0;
}
delete[] _str; //exception is thrown at this line
}
char**split(char*inputstr、char delim、int和count){
字符**ostr=NULL;
int numStr=0;
int i=0,j,指数=0;
while(inputstr[i]){
if(inputstr[i++]==delim)
numStr++;
}
if(inputstr[i-1]!=delim)
numStr++;
计数=numStr;
ostr=新字符*[numStr];
i=0;
while(inputstr[i])
{
j=i;
while(inputstr[j]&&inputstr[j]!=delim)
j++;
ostr[index]=新字符[j-i+1];
//istr[j]=0;
strncpy(ostr[index],inputstr+i,j-i);
ostr[index++][j-i]=0;
i=j+1;
}
返回ostr;
}
对于(int i=0,countStr;i很难看到任何错误,您的索引可能有问题,导致拆分函数中的缓冲区溢出,只有在尝试删除字符**数组时才会捕获该溢出
转换成carlpett推荐的std::string和std::vectors怎么样(这是一个很好的建议)
大概是这样的:
void split(const std::string& str_, char delimiter_, std::vector<std::string>& result_)
{
std::string token;
std::stringstream stream(str_);
while( std::getline(stream, token, delimiter_) ) result_.push_back(token);
}
void split(常量std::string&str,字符分隔符,std::vector&result)
{
字符串标记;
std::stringstream流(str_u);
while(std::getline(流、令牌、分隔符)result\uu.push\u back(令牌);
}
然后,您只需使用字符串、分隔符和一个空的std::vector调用它,并最终得到一个填充的子字符串向量。您不必使用new/delete和担心内存问题。您有理由使用c字符串和原始数组吗?std::string
和std::vector
可能会在这方面对您有很大帮助n指出确切的错误是什么,到目前为止您已经尝试了什么,并尝试将代码还原到最小的失败(但编译失败)你是否考虑过用ValGrand运行这个程序?我使用RAW数组,因为我不能在这个项目中使用向量。确切的错误是堆损坏,我尝试用断点进行调试,错误出现在在线删除[]中。_str,rest all正常工作。不,我对Valgrind一无所知。我应该使用它吗?它会有什么帮助?Valgrind将有助于查明堆损坏的来源(在大多数情况下可以精确到行号)如果您所在的平台支持此用例,那么它是此用例的完美工具。为什么要将结果作为参数传递而不是返回它?更好的是,建议使用内置标记拆分的boost。我们将拆分的ted字符串作为2D字符数组返回,并通过引用将字符串数作为argumnet传递,因为我们无法返回urn两件事。@KillianDS-在那个例子中,我将结果作为参数传递,因为我想避免作为返回值使用时会出现的副本。@brandx:返回值优化很可能会被应用,并且至少会使用右值引用给出C++11的替代方案。这是一个糟糕的设计,这是如此多无法读取的API的原因@KillianDS-为什么要依赖编译器来执行RVO?我更愿意使用我在这里提供的参数,以便在其他地方重用该向量。至于C++11,这很酷,但C++11在被问到这个问题时已经存在了好几天。如果您有C++11替代方案,请提供一个替代答案。