如何在一个初始化为唯一指针的动态数组中存储一个字符串(来自具有n行数的文件)? C ++

时间:2016-09-30 05:54:20

标签: c++ arrays

寻找指导的学生......

这是一个带有说明的课程作业: 使用unique_ptr对象作为数据成员重写您的程序,Chore List。您应该在unique_ptr对象中存储动态数组。使用此数组存储,检索,删除和更新家务。

我正在尝试了解有关使用unique_ptr对象的更多信息,因此我可以创建应该初始化列表的构造函数。文本文件具有列表,构造函数应将该列表存储到数组中。我正在尝试解决错误"访问违规读取位置。"在原始程序中,我创建了一个具有更大容量的临时动态数组,并将列表复制到该数组中。在文本文件中有10个杂项的列表。这是代码:

在标题中:

private:
    /* var to keep len of list */
    int len = 0;
    int max = 9;
    /* add appropriate data structure to store list */
    string *arr = new string[max];

在.cpp:

/* reads the file line by line and initializes list */
ListOfChores::ListOfChores(string fileName){
    ifstream file(fileName, ifstream::in);
    string line;
        if (file.is_open()) //Checking if the file can be opened
        {
        while (getline(file, line)) // Gets a single line
        {
            if (len >= max)
            {
                string *narr = new string[max + 10]; // New, larger array
                for (int i = 0; i < max; i++)
                {
                    narr[i] = arr[i]; // Copies line
                }
                delete[] arr; // Clears
                arr = narr; // Copies
                max += 1; // Growth
            }
            arr[len] = line; // Store a line in the array
            len++; // Increases length by 1
        }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl;
}

并表明我一直在研究这个并且不是一个懒惰的学生......

新程序尝试标题:

private:
    /* var to keep len of list */
    int len = 0;
    int max = 9;
    /* add appropriate data structure to store list */
    string *arr = new string[max]; // Primary array
    string *narr = new string[max]; // New array

新程序.cpp:

/* reads the file line by line and initializes list */
ListOfChores::ListOfChores(string fileName) {
    unique_ptr<string[]> arr(new string[max]); // Unique pointer initialization

    ifstream file(fileName, ifstream::in);
    string line = " ";
    if (file.is_open()) //Checking if the file can be opened
    {
        while (getline(file, line)) // Gets lines from file
        {
            if (len >= max)
            {
                max++; // Growth
                unique_ptr<string[]> narr(new string[max]); // New unique pointer
                narr = move(arr);// narr owns the object
                narr[max] = line; // Store a line in the array
                len++; // Increases length by 1
                arr = move(narr); // arr owns the object
            }
            else
            {
                arr[len] = line; // Store a line in the array
                len++; // Increases length by 1
            }
        }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl;
}

1 个答案:

答案 0 :(得分:0)

unique_ptr的全部内容是在unique_ptr超出范围时销毁托管指针。这意味着您不希望它在任何受限范围内声明。一旦退出当前代码块,您所做的任何工作都将被销毁。在函数内部创建但未返回给调用者的unique_ptr消失了,并且一旦函数返回,它的内容就会消失。如果您有一个用于存储动态数据量的类,则应该在对象的范围内管理数据。

所以

private:
    /* var to keep len of list */
    int len = 0;
    int max = 20; // made bigger so first 50% increase is 10 elements
    /* add appropriate data structure to store list */
    std::unique_ptr<std::string[]> arr; // Primary array
    // no need for New array here

可以在此处找到关于50%或100%阵列大小增加是否更好的讨论:What is the ideal growth rate for a dynamically allocated array?。与往常一样,您的里程可能会有所不同,但通常会同意一次增加一个坏主意。

现在进入ListOfChores,我们想要使用unique_ptr

ListOfChores::ListOfChores(string fileName) {
    //no unique_ptr here. Scope is too narrow to be useful    
    ifstream file(fileName, ifstream::in);
    string line = " ";
    if (file.is_open()) //Checking if the file can be opened
    {
        while (getline(file, line)) // Gets lines from file
        {
            if (len >= max)// the current size is too small Let's make it bigger!
                           // if we grow before adding the line, we don't need any 
                           // special code to add the new line.
            {
                max *= 1.5; // Grow by 50%. Numerous studies have shown that 50% is a 
                            // good balance of RAM vs copy overhead in the general case
                std::string * narr = new string[max]; // no unique_ptr here either
                // old school copy for simplicity and obviousness
                for (int index = 0; index < len; index++)
                {
                     narr[index] = arr[index]
                } 
                arr.reset(narr); // frees and replaces the old array
                                 // arr now manages narr
            }
            // done growing, add normally to array 
            arr[len] = line; // Store a line in the array
            len++; // Increases length by 1
        }
        file.close(); // Closes file
    }
    else cout << "Unable to open file" << endl;
}

其他ListOfChores成员函数将根据需要使用arr,读取,添加和减去。为了有效地添加,应该从构造函数中删除数组增长代码,并将其置于private方法中,以便构造函数和其他需要放大数组的方法调用。