【问题标题】:c++ Error in free when using array as parameter使用数组作为参数时c ++免费错误
【发布时间】:2017-06-25 16:22:01
【问题描述】:

我已经阅读了许多具有相同错误的帖子,不幸的是,所有这些帖子都涉及从数组末尾索引。在我的情况下,当我将数组分配给构造函数中的变量时出现错误。

这是我的代码:

Heap.cpp

#include "./Heap.h"
#include <iostream>
#include <sstream>
// Provides floor, ceil, etc.
#include <cmath>

using namespace std;

Heap::Heap() {
  arraySize = 0;
  n = 0;
  A = NULL;
}

// This assumes that every element of the array is an
// element of the heap.
Heap::Heap(int* inArray, int inArraySize, int inHeapSize) {
  // TODO: initialize your class data members. An array dynamically allocated
  // as follows:
  // A = new int[size];
  // If you allocate an array like this you MUST deallocate it in your
  // destructor. This is done for you in the destructor below.

  arraySize = inArraySize;
  n = inHeapSize;
  A = new int[arraySize];
  A = inArray;
}

// Destructor. Cleans up memory.
Heap::~Heap() {
  delete [] A;
}

// Note: the function name is prefixed by Heap:: (the class
// name followed by two colons). Any function defined in
// the .cpp file must have this prefix.
int Heap::at(int i) const {
  return A[i];
}

int Heap::parent(int i) const{
    return (int) (i - 1) / 2;
}

int Heap::left(int i) const {
    return (i + 1)* 2 - 1;
}

int Heap::right(int i) const {
    return  (i + 1) * 2;
}

bool Heap::hasLeft(int i) const {
    int leftIndex = left(i);
    std::cout << "left index = " << leftIndex<< std::endl;
    return false; 
}

bool Heap::hasRight(int i) const{
    return false;
}

void Heap::maxHeapify(int i){

}
//
void Heap::buildMaxHeap(){

}



bool Heap::operator==(const Heap& rhs) {
  if (n != rhs.n) return false;
  for (int i = 0; i < n; ++i) {
    if (A[i] != rhs.A[i]) return false;
  }
  return true;
}

bool Heap::operator==(const int* rhs) {
  for (int i = 0; i < n; ++i) {
    if (A[i] != rhs[i]) return false;
  }
  return true;
}

std::ostream& operator<<(std::ostream& out, const Heap& h) {
  out << "[";
  for (int i = 0; i < h.n; ++i) {
    out << h.A[i];
    if (i < h.n-1) {
      out << ", ";
    }
  }
  out << "]";
  return out;
}

string toDotImpl(const Heap& h, int i) {
  using namespace std;
  stringstream ss;
  if (h.hasLeft(i)) {
    ss << toDotImpl(h, h.left(i));
    ss << "\"" << h.at(i) << "\" -> \""
       << h.at(h.left(i)) << "\"\n";
  }
  if (h.hasRight(i)) {
    ss << toDotImpl(h, h.right(i));
    ss << "\"" << h.at(i) << "\" -> \""
       << h.at(h.right(i)) << "\"\n";
  }
  return ss.str();
}

string toDot(const Heap& h) {
  using namespace std;
  stringstream ss;
  ss << "digraph G {\n";
  ss << "graph [ordering=\"out\"]\n";
  ss << "\"" << h.at(0) << "\"\n";
  ss << toDotImpl(h, 0);
  ss << "}\n";
  return ss.str();
}

Heap.h

#pragma once

// Provides I/O
#include <iostream>
// Provides size_t
#include <cstdlib>
// Provides INT_MAX and INT_MIN
// You can consider INT_MIN to be negative infinity
// and INT_MAX to be infinity
#include <climits>

//------------------------------------------------------------
// Heap class
//------------------------------------------------------------
class Heap {
 public:
  // Constructor
  Heap();

  // This constructor assumes that every element of the array is an
  // element of the heap.
  Heap(int* inArray, int inArraySize, int inHeapSize);

  // Destructor
  ~Heap();

  // Accesses an element of the array.
  int at(int i) const; 

  // Gets parent index of element at i
  int parent(int i) const;

  // Return element to the  left of i
  int left(int i) const;

  // Return element to the right of i
  int right(int i) const;

  // Checks if an element has a left child
  bool hasLeft(int i) const;

  // Checks if an elemnt has a right child
  bool hasRight(int i) const;

  // "Max heapifies" an array
  void maxHeapify(int i);

  // builds a max heap
  void buildMaxHeap();


  // Allows comparison between results
  bool operator==(const Heap& rhs);
  bool operator==(const int* rhs);

  // Useful for debugging. To use:
  //   Heap h;
  //   cout << h << endl;
  friend std::ostream& operator<<(std::ostream& out, const Heap& h);

 private:
  // The array
  int* A;

  // Size of the array
  int arraySize;

  // The number of elements in the heap
  int n;
};

// Useful for debugging. To use:
//   Heap h;
//   cout << h << endl;
std::string toDot(const Heap& h);

调用代码时,如果需要,我可以包含整个 main.cpp,但它有几百行被注释掉的测试用例。 int A[] = { 1, 2, 3, 4, 5, 6, 7, 8 }; Heap h(A, 8, 8);

如果我注释掉A = inArray;,程序就会运行,所以我非常有信心这就是问题所在。

AHeap.h 中定义为`int* A;

这是完整的错误:

*** `./project' 中的错误:free():无效大小:0x00007ffd84786660 *** 中止(核心转储)

这可能是一个相当简单的问题,但我不知道是什么原因造成的,因为我认为这应该分配一个 inArraySize 大小的 int 类型数组,然后将给定的数组 inArray 分配给 A。

完全披露:这是作业的一部分,因此请随时为我指明正确的方向,但我的教授对我们使用 stackoverflow 没有意见,只要我们将其设置为站点即可。

【问题讨论】:

  • ... 错误是什么? (以及它在哪一行等)
  • 您正在分配内存,然后在下一行您通过重新分配A 立即丢弃该内存的地址。这真的是你想做的吗?
  • 请发布完整的、最小的和可编译的示例。您提供的代码缺少例如 arraySizen 的声明。
  • 行在哪里A = inArray;???

标签: c++ arrays memory-management


【解决方案1】:

您正在尝试复制一个数组,但分配这样的指针并不是这样做的。有多种方式。

标准 C++:

#include <algorithm>

std::copy(inArray, inArray + inArraySize, A);

使用标准容器:

#include <vector>

std::vector<int> A(inArray, inArray + inArraySize);

老式C方式

memcpy(A, inArray, sizeof(int) * inArraySize);

【讨论】:

  • 这成功了,对于重复的问题我很抱歉,我是 C++ 新手,并认为只是分配值会复制它,但是在阅读了重复链接中的答案后,我明白了为什么它没有
【解决方案2】:

在做:

A = new int[arraySize];
A = inArray;

就像在做:

i = 5;
i = 6;

第二个赋值覆盖第一个。


因此,成员变量A 指向输入参数inArray 指向的同一内存块。

如果你没有动态分配这个内存块(new),那么你不能动态地释放它(delete)。

【讨论】:

  • 感谢您指出我只是覆盖了 A,我之前没有意识到这一点。很抱歉在我的问题中编辑代码,您的回答很有帮助。
【解决方案3】:

线条

A = new int[arraySize];
A = inArray;

是两个问题的原因。

  1. 存在内存泄漏。 new int[arraySize] 返回的值丢失,无法释放。

  2. 如果你在析构函数中调用delete [] A,那将是第二个问题的原因。

    • 如果inArray 在调用函数中被动态分配和释放,您将在同一个指针上调用delete 两次。
    • 如果inArray 是在堆栈中创建的数组,则在其上调用delete 也是一个问题。 delete 只能在调用new 返回的内存上调用。

【讨论】:

  • 感谢您的回答,我现在对 C++ 中的数组有了更多的了解。
【解决方案4】:

A = inArray; 没有做你认为它正在做的事情。此行inArray 复制到您为A 分配的内存中。相反,它会将A 更改为指向一个新位置(inArray 的地址),从而导致先前分配的内存泄漏。稍后当您在A 上调用delete 时,您将尝试在inArray 的地址释放内存。

如果你只想复制一个数组,你可以这样做

A = new int[inArraySize];
for (i = 0; i < inArraySize; ++i)
    A[i] = inArray[i];

或者更好,std::copy:

std::copy(inArray, inArray + inArraySize, A);

【讨论】:

  • @acraig5075 领先您一分钟,但感谢您的回答
猜你喜欢
  • 2021-11-28
  • 2015-12-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-05-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多