繁体   English   中英

C ++多维数组生成分段错误?

[英]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);

这是因为每次您都有效地将指针tmpNametmpSurName存储在数组details 然后,在下一次迭代中,您将覆盖tmpNametmpSurName指向的内存内容,因此最后,您将得到一个包含姓氏/姓氏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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM