删除字符串后C++检测到堆损坏
Heap corruption detected in C++ after removing strings
运行此代码时,出现错误
,如下图所示。我试过在 GCC 编译器上运行它,它工作正常。但是当在Windows上的Visual Studio上运行它时,出现了此错误:
调试错误!
程序:C:\Users\yudab\source\repos\Project2\Debug\Project2.exe
检测到堆损坏:在0x014FD2E0的正常块 (#153( 之后。
CRT 检测到应用程序在堆缓冲区结束后写入内存。
经过一些测试,似乎只有在尝试删除第二个单词后才会出现错误。
#include <cstring>
#include <string>
#pragma warning(disable : 4996)
#include <iostream>
using namespace std;
void delStr(char**& lexicon, int& lexSize, char word[]);
void printAll(char** lexicon, int lexSize);
void retract2dArr(char**& arr, int& size);
int main() {
char** lexicon = new char* [3];
lexicon[0] = new char[6]{ "hello" };
lexicon[1] = new char[5]{ "test" };
lexicon[2] = new char[6]{ "world" };
int size = 3;
char removeTest[5] = { "test" }; //The first word I want to remove from the list
char removeWorld[6] = { "world" }; //The second word I want to remove from the list
printAll(lexicon, size); //First prints the entire list
delStr(lexicon, size, removeTest); //Removes the first word
delStr(lexicon, size, removeWorld); //Removes the second word
printAll(lexicon, size); //Prints the list after deleting the words
return 0;
}
void delStr(char**& lexicon, int& lexSize, char word[]) {
bool toDelete = false;
for (int i = 0; i < lexSize; i++) {
if (strcmp(lexicon[i], word) == 0) {
toDelete = true;
for (; i < lexSize - 1; i++) {
strcpy(lexicon[i], lexicon[i + 1]);
}
}
}
if (toDelete == true) {
delete[] lexicon[lexSize - 1];
retract2dArr(lexicon, lexSize);
}
return;
}
void printAll(char** lexicon, int lexSize) {
for (int i = 0; i < lexSize; i++) {
cout << lexicon[i];
if (i != lexSize - 1) {
cout << " ";
}
}
cout << endl;
return;
}
void retract2dArr(char**& arr, int& size) {
size--;
char** newArr = new char* [size];
for (int i = 0; i < size; i++) {
*(newArr + i) = *(arr + i);
}
printAll(newArr, size);
delete[] arr;
arr = newArr;
return;
}
你不能strcpy
一个string
来another
if (strcmp(lexicon[i], word) == 0) {
toDelete = true;
for (; i < lexSize - 1; i++) {
strcpy(lexicon[i], lexicon[i + 1]);
}
}
因为每个字符串length
会有所不同。
例:
lexicon[0] = new char[6]{ "hello" };
lexicon[1] = new char[5]{ "test" }; // length is 4
lexicon[2] = new char[6]{ "world" }; // length is 5
第3 个字符串不适合第 2 个字符串,它会导致越界访问。
正如基兰·比拉达(kiran Biradar(指出的那样,strcpy
是这里的罪魁祸首。尽管与其将词典中的每个单词复制到为前一个单词分配的内存中,不如简单地将指针移回lexicon
数组中。
为您的delStr
函数尝试这样的事情:
void delStr(char**& lexicon, int& lexSize, char word[]) {
for (int i = 0; i < lexSize; i++) {
if (strcmp(lexicon[i], word) == 0) {
delete[] lexicon[i];
for (; i < lexSize - 1; i++) {
lexicon[i] = lexicon[i + 1];
}
retract2dArr(lexicon, lexSize);
}
}
}
附言您不需要使用toDelete
标志,您可以在第一个if
内调用retract2dArr
函数。
相关文章:
- 检测到堆损坏:在正常块 c++ 动态 2D 数组之后
- 删除字符串后C++检测到堆损坏
- 检测到堆损坏(字符串导致堆损坏)|C++
- 在C++中检测到堆损坏错误
- C++ 内存损坏检测
- 如何修复检测到堆损坏:正常阻止后
- 在复制 delete[] 数组后在 C++ 中检测到堆损坏
- 从检测到 glibc 正常退出 - malloc():内存损坏
- 编译器如何检测内存损坏
- 排序程序的错误(检测到堆损坏)
- 正常块错误后检测到的堆损坏
- C++ 删除数组时检测到堆损坏
- 调试错误,在C++中检测到堆损坏
- 检测到堆损坏(类方法)
- 在普通块(#164)之后检测到堆损坏
- jemalloc未检测到内存损坏
- 检测到合并排序堆损坏
- 堆损坏检测(模拟动态数组与静态数组)
- 堆损坏检测:在正常块之后(#153)
- QwtPlot - 堆损坏检测