动态扩展指针数组
Dynamically Expanding An Array of Pointers
我正在尝试使用 C++ 构建字典。
字典必须随时动态创建和更新。
例如,假设我的词典中有 5 个词,我想添加另一个词,我必须创建一个新词典,其中有 6 个词的空间,复制旧词并将新词添加到新词典中。
在我的 main
函数中,我创建了一个 lexicon**
(指向指针数组的指针,因为每个单词都有一个指向它的 char
指针)。
我创建了一个 newStr
函数来接收新单词并将其添加到字典中并按字母顺序对其进行排序。
程序运行一次,但当我想添加另一个词时,我收到访问冲突警告:
0xC0000005: Access violation reading location 0xDDDDDDDD.
我不明白我做错了什么。感谢您的帮助!
这是我的代码:
#define MAX 80
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
void newStr(char** lexicon, int& lexiconSize, char word[])
{
// create the new updated lexicon
char** updated = new char*[++lexiconSize];
// copy the words from the old to the updated lexicon
for (int i = 0; i < lexiconSize; i++)
{
updated[i] = new char[MAX];
if (i < lexiconSize - 1)
{
strcpy_s(updated[i], MAX, lexicon[i]);
}
// add the new word to the end of the updatedLexicon
else
{
strcpy_s(updated[i], MAX, word);
}
}
// deallocate the memory of the worlds of the old lexicon
for (int i = 0; i < lexiconSize - 1; i++)
{
delete[] lexicon[i];
}
// deallocate the memory of the old lexicon
delete[] lexicon;
// point the lexicon pointer to the updatedLexicon
lexicon = updated;
// now sort the lexicon including the new word
if (lexiconSize > 1)
{
for (int i = 1; i < lexiconSize; i++)
{
for (int j = 1; j < lexiconSize; j++)
{
if (strcmp(lexicon[j - 1], lexicon[j]) > 0)
{
char t[MAX];
strcpy_s(t, MAX, lexicon[j - 1]);
strcpy_s(lexicon[j - 1], MAX, lexicon[j]);
strcpy_s(lexicon[j], MAX, t);
}
}
}
}
// deallocate the memory created for the updated lexicon
for (int i = 0; i < lexiconSize; i++)
{
delete[] updated[i];
}
delete[] updated;
return;
}
int main()
{
int lexiconSize = 3;
char** lexicon;
char word[MAX] = {};
// initialize lexicon for testing:
lexicon = new char*[lexiconSize];
lexicon[0] = new char[MAX];
strcpy_s(lexicon[0], MAX, "maybe");
lexicon[1] = new char[MAX];
strcpy_s(lexicon[1], MAX, "this");
lexicon[2] = new char[MAX];
strcpy_s(lexicon[2], MAX, "works");
cout << "enter the word to add" << endl;
cin >> word;
newStr(lexicon, lexiconSize, word);
// menu system that allows to add/delete/print the words
// delete the lexicon at the end of the program
for (int i = 0; i < lexiconSize; i++)
{ // delete the internal words
if (lexicon[i])
{
delete[] lexicon[i];
}
}
if (lexicon)
{
delete[] lexicon;
}
return 0;
}
- 这不是 C++ 代码:它是带有一些语法糖的 C。
- 不要在函数内部释放某些东西,如果你已经创建了它
在另一个地方。
- 使用智能指针。
- 您真的认为您的实施会更有效吗
和饮用水,比 std::vector/std::map?
您的问题是 lexicon
按值传递给 newStr()
。
分配 lexicon = updated
因此对调用者不可见。
由于函数释放了 lexicon[i]
引用的所有动态分配的内存,因此 main()
中 lexicon
的所有后续使用都具有未定义的行为。
顺便说一下,newStr()
中分配的所有内存都已泄漏 - 在函数 returns 之后没有变量引用它,因此无法在代码中释放它。
与其尝试直接使用指针和运算符 new
,不如查找标准容器 (std::vector
) 和 std::string
(用于管理字符串数据)。
我正在尝试使用 C++ 构建字典。 字典必须随时动态创建和更新。 例如,假设我的词典中有 5 个词,我想添加另一个词,我必须创建一个新词典,其中有 6 个词的空间,复制旧词并将新词添加到新词典中。
在我的 main
函数中,我创建了一个 lexicon**
(指向指针数组的指针,因为每个单词都有一个指向它的 char
指针)。
我创建了一个 newStr
函数来接收新单词并将其添加到字典中并按字母顺序对其进行排序。
程序运行一次,但当我想添加另一个词时,我收到访问冲突警告:
0xC0000005: Access violation reading location 0xDDDDDDDD.
我不明白我做错了什么。感谢您的帮助!
这是我的代码:
#define MAX 80
#include <iostream>
#include <cstring>
#include <string.h>
using namespace std;
void newStr(char** lexicon, int& lexiconSize, char word[])
{
// create the new updated lexicon
char** updated = new char*[++lexiconSize];
// copy the words from the old to the updated lexicon
for (int i = 0; i < lexiconSize; i++)
{
updated[i] = new char[MAX];
if (i < lexiconSize - 1)
{
strcpy_s(updated[i], MAX, lexicon[i]);
}
// add the new word to the end of the updatedLexicon
else
{
strcpy_s(updated[i], MAX, word);
}
}
// deallocate the memory of the worlds of the old lexicon
for (int i = 0; i < lexiconSize - 1; i++)
{
delete[] lexicon[i];
}
// deallocate the memory of the old lexicon
delete[] lexicon;
// point the lexicon pointer to the updatedLexicon
lexicon = updated;
// now sort the lexicon including the new word
if (lexiconSize > 1)
{
for (int i = 1; i < lexiconSize; i++)
{
for (int j = 1; j < lexiconSize; j++)
{
if (strcmp(lexicon[j - 1], lexicon[j]) > 0)
{
char t[MAX];
strcpy_s(t, MAX, lexicon[j - 1]);
strcpy_s(lexicon[j - 1], MAX, lexicon[j]);
strcpy_s(lexicon[j], MAX, t);
}
}
}
}
// deallocate the memory created for the updated lexicon
for (int i = 0; i < lexiconSize; i++)
{
delete[] updated[i];
}
delete[] updated;
return;
}
int main()
{
int lexiconSize = 3;
char** lexicon;
char word[MAX] = {};
// initialize lexicon for testing:
lexicon = new char*[lexiconSize];
lexicon[0] = new char[MAX];
strcpy_s(lexicon[0], MAX, "maybe");
lexicon[1] = new char[MAX];
strcpy_s(lexicon[1], MAX, "this");
lexicon[2] = new char[MAX];
strcpy_s(lexicon[2], MAX, "works");
cout << "enter the word to add" << endl;
cin >> word;
newStr(lexicon, lexiconSize, word);
// menu system that allows to add/delete/print the words
// delete the lexicon at the end of the program
for (int i = 0; i < lexiconSize; i++)
{ // delete the internal words
if (lexicon[i])
{
delete[] lexicon[i];
}
}
if (lexicon)
{
delete[] lexicon;
}
return 0;
}
- 这不是 C++ 代码:它是带有一些语法糖的 C。
- 不要在函数内部释放某些东西,如果你已经创建了它 在另一个地方。
- 使用智能指针。
- 您真的认为您的实施会更有效吗 和饮用水,比 std::vector/std::map?
您的问题是 lexicon
按值传递给 newStr()
。
分配 lexicon = updated
因此对调用者不可见。
由于函数释放了 lexicon[i]
引用的所有动态分配的内存,因此 main()
中 lexicon
的所有后续使用都具有未定义的行为。
顺便说一下,newStr()
中分配的所有内存都已泄漏 - 在函数 returns 之后没有变量引用它,因此无法在代码中释放它。
与其尝试直接使用指针和运算符 new
,不如查找标准容器 (std::vector
) 和 std::string
(用于管理字符串数据)。