【问题标题】:Segmentation fault in memory allocation when making a dynamically resized array C++制作动态调整大小的数组 C++ 时内存分配中的分段错误
【发布时间】:2021-12-09 08:37:43
【问题描述】:

append(int val) 函数运行时出现分段错误,并以多态方式调用,但我看不到 memalloc 错误来自何处。我还是 C++ 新手,经常遇到这个问题,但是当我自己修复它时,总是碰巧。任何指针? (不是双关语,或者是:))

整数组合.h

#ifndef INTEGERCOMBINATION_H
#define INTEGERCOMBINATION_H


using namespace std;

class IntegerCombination
{
public:
    IntegerCombination();
    void append(int Val);
    virtual int combine() = 0;
protected:
    int* _collection;
    int _length;
};

#endif

整数组合.cpp

#include "IntegerCombination.h"

IntegerCombination::IntegerCombination()
{
    _length = 0;
}

void IntegerCombination::append(int val)
{
    int newValPos = _length;            // Stores current length as new position for new 
                                        // value
    int* temp = _collection;            //Stores current array
    delete _collection;                 // Deletes current array
    _length++;                          // Increases the length for the new array
    _collection = new int[_length];     // Creates a new array with the new length
    for(int i = 0; i < newValPos; i++)
    {
        _collection[i] = temp[i];       // Allocates values from old array into new array
    }
    _collection[newValPos] = val;       // Appends new value onto the end of the new array
}

Main.cpp


#include "IntegerCombination.h"
#include "ProductCombination.h"

using namespace std;

int main()
{

    ProductCombination objProd;

    for(int i = 1; i <= 10; i++)
    {
        objProd.append(i);
    }

    return 0;
}

注意:ProductCombination.h 和 ProductCombination.cpp 中的代码并不完全相关,因为在 .cpp 文件中,append(int val) 只是将追加调用委托给 IntegerCombination.h 中的基类

【问题讨论】:

  • 这里有几个错误。首先,使用deletenew[]。您需要改用delete[]。其次,您尝试使用temp,它指向您刚刚尝试指向delete 的数组。您需要在删除元素之前复制它们。第三,您的类型不遵循Rule of 3/5/0。这些错误中的任何一个都可能导致段错误。
  • @FrançoisAndrieux 请添加答案,Andog 可以接受。
  • 真正的错误在于老师(假设这是一个练习)没有先教 std::vector。
  • @PepijnKramer 我们在第一学期学习了 std::vector,但我们的讲师希望我们在第一年使用指针,然后一旦他了解内存分配方面发生了什么,以及它是如何分配的一切正常,我们可以继续使用 std::vector
  • 无关:如果您还没有,请熟悉the Rules of Three, Five, and Zero。您将为自己节省大量调试时间。

标签: c++ inheritance segmentation-fault polymorphism


【解决方案1】:

对于初学者来说,构造函数不会初始化数据成员_collection

IntegerCombination::IntegerCombination()
{
    _length = 0;
}

所以这个数据成员可以有一个不确定的值,并且使用带有这样一个指针的操作符 delete 调用未定义的行为。

此外,当您尝试分配数组时,您需要使用运算符delete [] 而不是delete

并且该类必须至少明确定义一个虚拟析构函数。也可以将复制构造函数和复制赋值运算符声明为已删除,或者显式定义它们。

函数append有几个错误。

如前所述,您需要在此语句中使用运算符delete []

delete _collection;

而不是运算符delete

但是这个操作符必须在新数组分配后调用。否则指针temp 将具有无效值

int* temp = _collection;            //Stores current array
delete [] _collection;                 // Deletes current array

也就是说,在将之前的数组的元素复制到新分配的数组后,需要删除它。

【讨论】:

  • 如果 _collection 以 0 个元素开头,我将如何初始化它?
  • @Andog 用文字 nullptr 初始化它。例如_collection = nullptr;
猜你喜欢
  • 1970-01-01
  • 2020-11-26
  • 2013-05-27
  • 2016-05-14
  • 1970-01-01
  • 2022-01-02
  • 1970-01-01
  • 2014-06-15
  • 1970-01-01
相关资源
最近更新 更多