【问题标题】:C++ Dynamic Array Member Variable AssignmentC++ 动态数组成员变量赋值
【发布时间】:2015-10-01 01:14:24
【问题描述】:

我在将新值分配给作为 IntersectionFlowRate() 类的数据成员变量的动态 int 数组时遇到问题。我可以在构造函数中初始化并打印数组的值。但是,当我将构造函数退出到另一个类,然后在 IntersectionFlowRate() 类中调用一个函数时,传入变量以覆盖数据成员的初始值,它将出现分段错误。我已经调试发现覆盖数组会导致段错误。并且即使尝试在其函数之一中访问动态数组也会出现段错误。

我的问题是如何从动态 int 数组成员变量的一个函数中编辑其值,即 setArrayElement(int index, int x)。

这是我的一些代码。抱歉,如果我不清楚或遗漏了一些荒谬的东西。我已经坚持了好几个小时了。

    #ifndef INTERSECTIONFLOWRATE_H
    #define INTERSECTIONFLOWRATE_H

    class IntersectionFlowRate
    {
    public:
        IntersectionFlowRate();
        ~IntersectionFlowRate();
        void setFlowCycle(int index, int flow);

    private:
        int* m_flowRateMotorCycle;

 };
 #endif

在.h文件中^

    #include "IntersectionFlowRate.h"
    #include <cstdlib>
    #include <iostream>
    #include <new>

    using namespace std;
    IntersectionFlowRate::IntersectionFlowRate()
    {
        const int SIZE = 4; //Constant for m_flowRates[] size

        //DYNAMIC MEMORY DELETE LATER
        m_flowRateMotorCycle = new int[SIZE];

        for(int i = 0; i < SIZE; i++){
            m_flowRateMotorCycle[i] = 0;
            cout << m_flowRateMotorCycle[i] << endl;
            cout << "WE GOT HERE" << endl;
        }
    }

    void IntersectionFlowRate::setFlowCycle(int index, int flow){
        cout << "INDEX: " << index << endl;
        cout << "FLOW: " << flow << endl;

        m_flowRateMotorCycle[index] = flow; //seg fault is here
    }

我有另一个类,它创建一个指向 IntersectionFlowRate() 对象的指针,然后调用它的 setFlowCycle 函数,传入两个 VALID 整数。通过调试,我能够很好地将 0 和 3 传递给函数 setFlowCycle(0, 3) 并在函数中输出这些变量。

    #ifndef TRAFFICSIM_H
    #define TRAFFICSIM_H

    #include "IntersectionFlowRate.h"

    using namespace std;

    class TrafficSim
    {
    public:
        TrafficSim(); //Default Constructor
        TrafficSim(const char* file); //Constructor
        ~TrafficSim(); //Destructor


    private:
        IntersectionFlowRate* m_flowRate;
    };
    #endif


    #include "TrafficSim.h"
    #include "IntersectionFlowRate.h"
    #include <iostream>
    #include <string>
    #include <fstream>
    #include <cstdlib>


    using namespace std;

    TrafficSim::TrafficSim()
    {

        IntersectionFlowRate* m_flowRate = new IntersectionFlowRate();
        m_flowRate->setFlowCycle(0, 3);

    }

我用这段代码复制了错误。如果没有其他人可以,我完全不确定可能出了什么问题。

【问题讨论】:

  • 您应该提供MCVE
  • minimal 示例不是您认为问题所在的代码,它是复制问题的最小可能完整代码。我的猜测是你有一个rule of 0/3/5 违规。发布一个完整的例子。
  • A simple test 没有给我分段错误。您是否正确定义(并在需要时对其进行初始化)m_flowRateCar
  • 在现实生活中你会使用vector&lt;int&gt; 而不是int *,我假设你这样做是为了学习?
  • 我什至不知道在线 C++ IDE 的存在。下次我一定会使用它。谢谢。

标签: c++ arrays memory dynamic


【解决方案1】:

您正在设置一个名为 m_flowRate 的局部变量,而不是您的 TrafficSim 类的成员变量 m_flowRate

而不是这个:

TrafficSim::TrafficSim()
{
    IntersectionFlowRate* m_flowRate = new IntersectionFlowRate();
    m_flowRate->setFlowCycle(0, 3);
}

应该是这样的:

 TrafficSim::TrafficSim()
 {
    m_flowRate = new IntersectionFlowRate();
    m_flowRate->setFlowCycle(0, 3);
 }

但总的来说,它不需要是指针。它可能是您班级中的对象成员。这会稍微减少指针的使用:

class TrafficSim
{
    public:
        TrafficSim(); //Default Constructor
        TrafficSim(const char* file); //Constructor

    private:
        IntersectionFlowRate m_flowRate;
};

然后:

TrafficSim::TrafficSim()
{
    m_flowRate.setFlowCycle(0, 3);
}

关于如何在课堂上使用 std::vector 的问题,这里是 IntersectionFlowRate 类的代码示例,使用 vector 重写:

Vector sample

另外,问题的另一个来源是,当您的类中有指向动态分配内存的指针时,您的类未能遵循Rule of 3

使用std::vector 会自动处理此问题,但如果您坚持使用指针,则需要遵守发布链接中的说明。

【讨论】:

  • 太棒了,这修复了它。太感谢了。具有讽刺意味的是,我在几个小时前就读到了这个答案,但我压力太大了,我一定是错过了。
【解决方案2】:

是的,使用 std::vector,它更简单,而且它是一个模板,因此它也非常快并且适用于任何类型(最适合原始类型或指向对象的指针),它还具有边界检查和其他有用的东西。

如果您需要快速的类似数组的访问,那么您可以使用 std::map 将键与值相关联,就像这样

    std::map<UINT, YourClass*> m_mapIDs_to_YourClass;

当您第一次开始使用 stl 容器时,它们可能看起来有点奇怪,但不久之后您就离不开它们了,幸运的是它们已经成为 C++ 标准的一部分已有一段时间了。

这两个容器的边界检查可以通过将您的迭代器与 mapYourMap.end() 进行比较来完成,如果它们相等,则您已经传递了最后一个元素并且尝试通过迭代器访问数据将导致异常。 std::vector 的示例(如果 vecInt 是一个向量):

    vector<int>::iterator it = vecInt.begind();
    if (it == vecInt.end()) return; // vector is empty
    do {  // runs through elememts until out of bound, useful for searching
        i++
    while (it != vecInt.end());

【讨论】:

  • 建议扩展边界检查位,因为绝大多数向量调用不进行边界检查。 The one exception I know of is at.
  • 不,不是自动的,那会很浪费,但你可以这样做 vector::iterator it = vecType.begin();它++; if (it == vecType.end()) ; // 传递最后一个元素
  • 我添加了信息,是否足够清楚或者我应该添加示例代码?
  • 我的意思是你可以做边界检查,你不能在一个简单的数组上做。如果调用自动进行边界检查,则很难优化搜索和排序算法等内容
  • std::begin 和 std::end 将迭代器支持扩展到静态数组。动态的......好吧,你自己,孩子。
猜你喜欢
  • 1970-01-01
  • 2015-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-08-31
相关资源
最近更新 更多