使用数组作为参数时,免费出现c++错误

c++ Error in free when using array as parameter

本文关键字:免费 c++ 错误 数组 参数      更新时间:2023-10-16

我读过很多带有相同错误的帖子,不幸的是,所有这些帖子都涉及到从数组末尾进行索引。在我的例子中,当我将数组分配给构造函数中的一个变量时,会出现错误。

这是我的代码:

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;,程序就会运行,所以我很有信心这就是问题所在。

CCD_ 6在CCD_ 7中被定义为`int*A;

以下是完整的错误:

***`中出错/项目":free():无效大小:0x00007ffd84786660***中止(堆芯转储)

这可能是一个非常简单的问题,但我不知道是什么原因导致了这一点,因为我认为这应该在类型为int的ArraySize中分配一个大小为的数组,然后将给定的数组分配给a。

全面披露:这是一项任务的一部分,所以请随时为我指明正确的方向,但我的教授对我们使用stackoverflow很满意,只要我们在网站上。

您试图复制一个数组,但分配这样的指针并不是方法。有多种方法。

标准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);

执行:

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

就像做:

i = 5;
i = 6;

第二个赋值将覆盖第一个赋值。


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

如果您尚未动态分配此内存块(使用new),则无法动态解除分配(使用delete)。

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

是两个问题的原因。

  1. 内存泄漏。new int[arraySize]返回的值丢失,无法解除分配。

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

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

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);