在编辑显示此错误后运行程序后,我在编辑函数(unionSet)之前运行了此代码。我正在XCode上使用C ++进行工作,但之前尚未见过。
malloc: *对象0x100519860的错误:未分配要释放的指针 * 在malloc_error_break中设置一个断点进行调试
#include "Set.hpp"
#include <string>
#include <sstream>
#include <cassert>
using namespace std;
// Function for the default constructor.
Set::Set()
{
// default constructor
theSet = new int[0];
};
// Function for the overloaded constructor taking an element and building an array for it.
Set::Set(int element)
{
// take element
// make one memory box
// put element in that single box
numElements = 1;
theSet = new int[numElements];
for(int i = 0; i < numElements; i++)
theSet[i] = element;
};
// Function for the destructor.
Set::~Set()
{
// deletes the dynamic array
if (theSet != nullptr)
{
delete [] theSet;
// removes the posibility of a dangling pointer
theSet = nullptr;
}
};
// Function building the copy constructor.
Set::Set(const Set& copy)
{
// sets the value of copy constructor size equal to the current size by reference
numElements = copy.numElements;
// Allocate the memory.
theSet = new int[numElements];
// Copy all the data over.
for (int i = 0; i < numElements; i++)
theSet[i] = copy.theSet[i];
};
// Function for finding the elements in the intersection of set A and set B.
void Set::intersectSet(const Set& otherSet)
{
// only the elements in both sets
int *newSet = new int[otherSet.getCardinality()];
int x = 0;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++){
if (theSet[i] < otherSet.theSet[j])
{
i++;
}
else if (otherSet.theSet[j]< theSet[i])
{
j++;
}
else if (theSet[i] == otherSet.theSet[j])
{
theSet[i] = newSet[x];
i++;
j++;
x++;
}
theSet = newSet;
}
}
};
// Function for finding the elements in the union of set A and set B.
void Set::unionSet(const Set& otherSet)
{
// combine the two sets but no repeats
theSet = otherSet.theSet;
}
// Function for retreiving the difference between set A and set B.
void Set::setDifference(const Set& otherSet)
{
// the compliment of a set
// an array with values from array A and only array A(cannot be in B)
int *newSet = new int[otherSet.getCardinality()];
int x = 0;
for (int i = 0; i < 10; i++)
{
for (int j = 0; j < 10; j++){
if (theSet[i] < otherSet.theSet[j])
{
i++;
theSet[i] = newSet[x];
x++;
}
else if (otherSet.theSet[j] < theSet[i])
{
j++;
}
else if (theSet[i] == otherSet.theSet[j])
{
i++;
j++;
}
theSet = newSet;
}
}
};
// Function for checking if the "otherSet" is a subset of "theSet".
bool Set::isSubset(const Set& otherSet) const
{
// all elements of a must be in set b to be a subset
int i = 0, j = 0;
for ( i = 0; i < numElements; i++)
{
for ( j = 0; j < numElements; j++)
{
if ( theSet[i] == theSet[j] )
break;
}
if ( j == numElements)
return false;
// returns false if variable j is equal to the number of elements
}
return true;
// return true if the statement is not changed
};
// Function for checking if the set is empty.
bool Set::isEmptySet() const
{
// empty set = no memory
if (theSet != nullptr)
return false;
// returns true if the set is empty
return true;
// returns false if the set is not empty
};
// Function for checking if an element is a member of the set.
bool Set::isMember(int element) const
{
// check function looking for the element in the set
for (int i = 0; i < numElements; ++i)
{
if (theSet[i] == element) return true;
// returning true if the element is found
}
return false;
// return false if element is not found
};
// Function for retreiving the number of elements in the set.
int Set::getCardinality() const
{
// returns the size of the set over the first position
return (sizeof(theSet)/sizeof(*theSet));
};
string Set::toString()
{
// Builds the stream for output
stringstream stream;
// Opening stream statements when called
stream << "{ ";
// For loop for outputing the contents of set
for (int i = 0; i < numElements; i++)
stream << theSet[i] << ", ";
// Closing stream statements
stream << "}";
// Returns the whole statement to the output location.
return stream.str();
};
这段代码肯定是一个正在进行的工作,但是如果不弄清楚为什么会发生错误,我将无法继续前进。
测试文件如下所示:
#include <iostream>
#include "Set.hpp"
#include <string>
using namespace std;
// This function takes a method call as a string, a boolean value returned
// by a call and the expected boolean value and pretty prints the result.
void boolExpected(string method, bool val, bool expected)
{
if (expected)
cout << method << " = " << val << " expected true (1) ";
else
cout << method << " = " << val << " expected false (0) ";
if (expected == val)
cout << " [ PASS ]\n";
else
cout << " [ FAIL ]\n";
}
// This function takes a method call as a string, an integer value returned
// by a call and the expected integer value and pretty prints the result.
void intExpected(string method, int val, int expected)
{
cout << method << " = " << val << " expected " << expected;
if (expected == val)
cout << " [ PASS ]\n";
else
cout << " [ FAIL ]\n";
}
// This function takes a method call as a string, an integer value returned
// by a call and the expected integer value and pretty prints the result.
void stringExpected(string method, string val, string expected)
{
cout << method << " = " << val << " expected " << expected;
if (expected == val)
cout << " [ PASS ]\n";
else
cout << " [ FAIL ]\n";
}
// Tests the isEmptySet() method.
void testIsEmptySet()
{
Set mySet;
Set mySet2(3);
// added to see contents of array
cout << " mySet contains " << mySet.toString() << ". " << endl;
cout << " mySet2 contains " << mySet2.toString() << ". " << endl;
boolExpected("mySet.isEmptySet()", mySet.isEmptySet(), true);
boolExpected("mySet2.isEmptySet()", mySet2.isEmptySet(), false);
}
// Tests the isMember() method.
void testIsMember()
{
Set mySet;
Set* tmp;
// Build up a set.
Set mySet2(3);
tmp = new Set(4);
mySet2.unionSet(*tmp);
delete tmp;
tmp = new Set(7);
mySet2.unionSet(*tmp);
delete tmp;
// added to see what contents of array are
cout << " mySet contains " << mySet.toString() << ". " << endl;
cout << " mySet2 contains " << mySet2.toString() << ". " << endl;
boolExpected("mySet.isMember(5)", mySet.isMember(5), false);
boolExpected("mySet.isMember(7)", mySet.isMember(7), false);
boolExpected("mySet2.isMember(7)", mySet2.isMember(7), true);
boolExpected("mySet2.isMember(4)", mySet2.isMember(4), true);
boolExpected("mySet2.isMember(3)", mySet2.isMember(3), true);
boolExpected("mySet2.isMember(15)", mySet2.isMember(15), false);
}
// Tests the isSubset method.
void testIsSubset()
{
Set mySet(7);
Set* tmp;
// Build up a set.
Set mySet2(3);
tmp = new Set(4);
mySet2.unionSet(*tmp);
delete tmp;
tmp = new Set(7);
mySet2.unionSet(*tmp);
delete tmp;
// added to see what contents of array are
cout << " mySet contains " << mySet.toString() << ". " << endl;
cout << " mySet2 contains " << mySet2.toString() << ". " << endl;
boolExpected("mySet.isSubset(mySet2)", mySet.isSubset(mySet2), true);
boolExpected("mySet2.isSubset(mySet)", mySet2.isSubset(mySet), false);
}
// Tests the getCardinality method.
void testGetCardinality()
{
Set emptySet;
Set mySet(7);
Set* tmp;
// Build up a set.
Set mySet2(3);
tmp = new Set(4);
mySet2.unionSet(*tmp);
delete tmp;
tmp = new Set(7);
mySet2.unionSet(*tmp);
delete tmp;
// added to see what contents of array are
cout << " mySet contains " << mySet.toString() << ". " << endl;
cout << " mySet2 contains " << mySet2.toString() << ". " << endl;
intExpected("mySet.getCardinality()", mySet.getCardinality(), 1);
intExpected("mySet2.getCardinality()", mySet2.getCardinality(), 3);
intExpected("emptySet.getCardinality()", emptySet.getCardinality(), 0);
}
// Tests the unionSet method.
void testUnionSet()
{
Set emptySet;
Set mySet(7);
Set* tmp;
// Build up a set.
Set mySet2(3);
tmp = new Set(4);
mySet2.unionSet(*tmp);
delete tmp;
stringExpected("{ 3 } union { 4 } ", mySet2.toString(), "{ 3, 4 }");
tmp = new Set(7);
mySet2.unionSet(*tmp);
delete tmp;
stringExpected("{ 3, 4 } union { 7 } ", mySet2.toString(), "{ 3, 4, 7 }");
emptySet.unionSet(mySet);
stringExpected("{ } union { 7 }", emptySet.toString(), "{ 7 }");
}
// This tests the intersectSet() method.
void testIntersectSet()
{
Set emptySet;
Set mySet(7);
Set* tmp;
// Build up a set.
Set mySet2(3);
tmp = new Set(4);
mySet2.unionSet(*tmp);
delete tmp;
tmp = new Set(7);
mySet2.unionSet(*tmp);
delete tmp;
emptySet.intersectSet(mySet);
stringExpected("{ } intersect { 7 }", emptySet.toString(), "{ }");
mySet.intersectSet(mySet2);
stringExpected("{ 7 } intersect { 3, 4, 7 }", mySet.toString(), "{ 7 }");
mySet2.intersectSet(mySet);
stringExpected("{ 3, 4, 7 } intersect { 7 }", mySet2.toString(), "{ 7 }");
}
// This tests the setDifference method.
void testSetDifference()
{
Set mySet(7);
Set* tmp;
// Build up a set.
Set mySet2(3);
tmp = new Set(4);
mySet2.unionSet(*tmp);
delete tmp;
tmp = new Set(7);
mySet2.unionSet(*tmp);
delete tmp;
mySet.setDifference(mySet2);
stringExpected("{ 7 } difference { 3, 4, 7 }", mySet.toString(), "{ }");
Set mySet3(7);
mySet2.setDifference(mySet3);
stringExpected("{ 3, 4, 7 } difference { 7 }", mySet2.toString(), "{ 3, 4 }");
}
int main()
{
cout << "Testing isEmptySet()\n";
cout << "--------------------\n";
testIsEmptySet();
cout << endl << endl;
cout << "Testing isMember()\n";
cout << "------------------\n";
testIsMember();
cout << endl << endl;
cout << "Testing isSubset()\n";
cout << "------------------\n";
testIsSubset();
cout << endl << endl;
cout << "Testing getCardinality()\n";
cout << "------------------------\n";
testGetCardinality();
cout << endl << endl;
cout << "Testing unionSet()\n";
cout << "------------------\n";
testUnionSet();
cout << endl << endl;
cout << "Testing intersectSet()\n";
cout << "----------------------\n";
testIntersectSet();
cout << endl << endl;
cout << "Testing setDifference()\n";
cout << "-----------------------\n";
testSetDifference();
cout << endl << endl;
return 0;
}
输出在终端中显示为:
>Testing isEmptySet()
>--------------------
> mySet contains { }.
> mySet2 contains { 3, }.
>mySet.isEmptySet() = 0 expected true (1) [ FAIL ]
>mySet2.isEmptySet() = 0 expected false (0) [ PASS ]
>
>
>Testing isMember()
>------------------
> mySet contains { }.
> mySet2 contains { 0, }.
>mySet.isMember(5) = 0 expected false (0) [ PASS ]
>mySet.isMember(7) = 0 expected false (0) [ PASS ]
>mySet2.isMember(7) = 0 expected true (1) [ FAIL ]
>mySet2.isMember(4) = 0 expected true (1) [ FAIL ]
>mySet2.isMember(3) = 0 expected true (1) [ FAIL ]
>mySet2.isMember(15) = 0 expected false (0) [ PASS ]
>Set(13123,0x1003a8380) malloc: *** error for object 0x100519860: pointer being freed was not allocated
>*** set a breakpoint in malloc_error_break to debug
非常感谢您的帮助。
答案 0 :(得分:-1)
您的直接问题是由unionSet
引起的。它不执行联合操作,您正在复制一个指针,该指针将被调用方删除。释放的内存可能会在第二次删除之前重新使用。
您需要正确实现您的设置联合操作。
为避免将来出现问题,您还需要为Set
实现赋值运算符。