【问题标题】:Enlarge a dynamic array (no vector<> allowed, class assignment)扩大动态数组(不允许vector<>,类分配)
【发布时间】:2016-12-16 22:06:14
【问题描述】:

这是我要问的第一个问题,如有需要请仔细检查我:)

我正在尝试为学校的 C++ 课程解决一个问题。我遇到了一个我真的无法理解的错误。我正在编程。

作业说:

  • 两个类,

  • 使用的继承机制,

  • 使用动态内存分配保存学生的数据库,

  • 一种在不使用高级数据结构的情况下扩大数据库的方法,

  • 为已创建类的对象重载流操作符。

这是我的代码:

#include <conio.h>
#include <stdio.h>
#include <iostream>
#include <string.h>

using namespace std;

class Person
{
protected:

    char Name[20];
    string Surname;
    int Age;

public:

    virtual void whoAmI()=0;

    friend ostream &operator<< (ostream &out_, Person &s);             // stream overl.
    friend istream &operator>> (istream &in_, Person &s);
    friend void resizeArr(Person* oldList, int oldSize, int newSize);  // array enlarge
};

class Student :public Person
{
public:
    Student(){}
    Student(char name[], string surname, int age )
    {
        strcpy(Name, name);
        Surname = surname;
        Age = age;
    }

    virtual void whoAmI()                   // basically replaced by overloaded ostream
    {
        //cout << "I am a student\nMy name is " << name <<" "<< surname << "; I'm "<< age << " years old.";
        cout << Name << endl;
        cout << Surname << endl;
        cout << Age << endl;
    }
};

istream &operator>> (istream &in_, Person &s)   // through reference: stream object and overloading object
{
    cout << "New student record: "<< endl;
    cout << "Name: " << endl;
    in_ >> s.Name;
    cout << "Surname: " << endl;
    in_ >> s.Surname;
    cout << "Age: " << endl;
    in_ >> s.Age;
    cout << endl;
    return in_;
}

ostream &operator<< (ostream &out_, Person &s)
{
    out_ << "Name:\t\t" << s.Name << endl << "Surname:\t" << s.Surname << endl <<"Age:\t\t" << s.Age << endl;
    return out_;
}

void resizeArr(Student* oldList, int oldSize, int newSize)
{
    Student *newList = new Student[newSize];

    for(int i = 0; i < oldSize; i++)            // COPYING
    {
        newList[i]=oldList[i];
    }

    for(int i = oldSize ; i < newSize ; i++)    // init rest as blank students to avoid errors
    {
        newList[i] = Student( "undef" , "undef", 0);
    }

    delete [] oldList;                          // free memory used for old array
    oldList = newList;                          // reset pointer to new array
}

int main()
{
    int initSize = 2;
    int plusSize = 4;

    Student *list1 = new Student[initSize];

    for (int i=0; i<initSize; i++){                  // initialize each cell as a blank student
        list1[i] = Student(  "undef" , "undef", 0);
    }

    for (int i=0; i<initSize; i++)                   // display initial array
    {
        cout << list1[i] << endl << "------------------------------" << endl;  // for the sake of console output clarity
    }

    resizeArr(list1, initSize, plusSize);           // FUNCTION CALL

    cout << endl << "\tEnlarger database: " << endl << endl;                    // for the sake of console output clarity

    for (int i=0; i<plusSize; i++)               // display enlarged array
    {
        cout << list1[i] << endl << "------------------------------" << endl;  // for the sake of console output clarity
    }

    getch();
    return 0;
}

我之前使用整数数组对这种机制进行了原型设计,并且它有效......现在我因为未知原因而崩溃了。

请指点我正确的方向。


编辑:

程序编译并运行,新数组似乎保存了旧数组的前两个元素,当它到达第一个新元素时,程序崩溃了(内存单元似乎在诱骗我并持有一个笑脸)。

前两个Student对象被复制,第三个元素导致错误:

【问题讨论】:

  • 崩溃发生在哪里,错误信息是什么?
  • 调试器是解决此类问题的正确工具。 询问 Stack Overflow 之前,您应该逐行逐行检查您的代码。如需更多帮助,请阅读How to debug small programs (by Eric Lippert)。至少,您应该 [编辑] 您的问题,以包含一个重现您的问题的 Minimal, Complete, and Verifiable 示例,以及您在调试器中所做的观察。
  • (no vector&lt;&gt; allowed, class assignment) -- 要克服这些(IMO。愚蠢的)限制,请创建自己的简单 vector 类,而不是具有调整大小功能的专用“学生”或“人”类。你会学到很多东西(比如正确的内存管理),而且你可以在进一步的作业中使用该课程。就目前而言,您的程序没有为 Student 数组释放内存,因此从技术上讲存在内存泄漏。

标签: c++ arrays memory dynamic


【解决方案1】:

问题在于你的 resize 函数的定义:

void resizeArr(Student* oldList, int oldSize, int newSize)

除非另有说明,否则传递给函数的所有参数都是按值传递的。尽管第一个参数是一个指针,但它只允许修改它所指向的内存,而不是指针本身。

您需要将第一个参数的声明更改为Student **,并在方法中更改代码以处理双重取消引用,或者将其更改为Student*&amp;。 我怀疑你很幸运它适用于整数。

【讨论】:

    【解决方案2】:

    您将指向学生列表的指针传递给 resizeArr 例程,即 void resizeArr(Student* oldList, int oldSize, int newSize),但不是指向指针的指针。 因此,为 resizeArr 中的指针分配一个新的/不同的内存块将使 resizeArr 中的变量指向新地址,但传递给 resizeArr 的指针(即list1)不会改变。

    我建议将逻辑更改为Student* resizeArr(Student* oldList, int oldSize, int newSize) 并将其称为list1 = resizeArr(list1, initSize, plusSize);

    这类似于void* realloc (void* ptr, size_t size);的签名。

    【讨论】:

    • 可爱!我现在看到了错误,原来的指针本身没有被修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-18
    • 2021-05-08
    • 1970-01-01
    • 2014-09-14
    • 2011-02-06
    相关资源
    最近更新 更多