[英]C++ Multidimensional arrays generating segmentation faults?
我正在编写一个脚本,该脚本必须将一些名称复制到多维数组中,打印该数组的内容,然后释放内存并终止。 我遇到的问题是,当我运行脚本时,它只会打印出所输入的姓氏。 这是我所做的。 任何帮助将是巨大的! 提前致谢!
#include <iostream>
#include <string.h>
using namespace std;
void createArray(int n);
void addDetail(char*& name, char*& surname);
void printArray();
void clear();
char ***details;
int used;
int size;
int main()
{
createArray(3);
char* tmpName = new char[20];
char* tmpSurName = new char[120];
strcpy(tmpName, "nameA");
strcpy(tmpSurName, "surnameA");
addDetail(tmpName,tmpSurName);
strcpy(tmpName, "nameB");
strcpy(tmpSurName, "surnameB");
addDetail(tmpName,tmpSurName);
strcpy(tmpName, "nameC");
strcpy(tmpSurName, "surnameC");
addDetail(tmpName,tmpSurName);
clear();
return 0;
}
void createArray(int n)
{
details= new char**[n];
for(int i=0; i<n; i++)
details[i] = new char*[2];
size = n;
used = 0;
}
void addDetail(char*& name, char*& surname)
{
if(occupation < size)
{
details[used][0] = name;
details[used][1] = surname;
used++;
}else{
cout << "Array Full " << endl;
}
}
void printArray()
{
for(int i=0; i<used; i++)
cout << details[i][0] << " " << details[i][1] << endl;
}
void clear()
{
for(int i=0; i<size; i++)
{
delete [] details[i];
details[i] = 0;
}
delete [] details;
details=0;
}
您没有为details[used][0]
和details[used][1]
分配内存,因此它正在使用这些位置中的任何随机地址。
由于这是C ++,您也许可以使用字符串代替? std::string **details;
。 这将与您现有的代码一起工作,除了它将泄漏内存。
更好的是使用向量的向量。
像这样: std::vector<std::vector<std::string> > details;
然后, createArray
函数可以完全消失,并且addDetail
变得更简单:
std::vector<string> newName;
newName.push_back(name);
newName.push_back(surname);
details.push_back(newName);
这是因为每次您都有效地将指针tmpName
和tmpSurName
存储在数组details
。 然后,在下一次迭代中,您将覆盖tmpName
和tmpSurName
指向的内存内容,因此最后,您将得到一个包含姓氏/姓氏n次的列表。
要解决此问题,您需要在每次调用addDetail之前重新分配tmpName和tmpSurName。
顺便说一句,为什么您需要使用(ewww) char***
,而不能使用例如STL?
看起来正在发生的事情是您没有将字符串添加到数组中,而是添加了指向名称和姓氏的指针。 每个实例都指向该变量,因此,当您询问数组包含的内容时,它会询问名称和姓氏,后者仅包含最后一个值。
也是那个数组,您确定它能正常工作吗? 数组是……具体的东西。 您本质上说“我想要其中的5个,它们将如此大(根据您输入的类型而定)”,而计算机悄悄地走了“好吧,我会在这里为这些人留出空间,您可以在准备就绪时将其放入”。 当您的代码在其中放置这些名称时,实际上没有任何存储位置的准备。 如果您填满了那个空间并超越了您,那就去糟糕的地方。 因此,您应该做的是使char ***的最后一个*成为char [120]的指针,这样您就知道(至少出于您的目的)它永远不会被填充。 创建外部数组之后,请在createArray函数中执行此操作。
您将继续覆盖临时缓冲区,而不是为数组中的每个条目创建新缓冲区。 结果,只有最后写入缓冲区的数据才能幸免。
尽管该示例可能存在一些问题,但是这是一种解决方法的粗略指南-我没有尝试进行编译或测试。
main的这一部分属于addDetail:
char* tmpName = new char[20];
char* tmpSurName = new char[120];
strcpy(tmpName, "nameA");
strcpy(tmpSurName, "surnameA");
因此,您的新addDetail如下所示:
void addDetail(char*& name, char*& surname)
{
if(occupation < size)
{
details[used][0] = new char[20];
details[used][1] = new char[120];
strcpy(details[used][0], name);
strcpy(details[used][1], surname);
used++;
}else{
cout << "Array Full " << endl;
}
}
它会像下面这样从main调用:
addDetail("nameA", "surnameA");
不过,您需要更新clear才能正确清理在addDetail中所做的分配。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.