我试图了解字符串数组和核心转储。因此,我创建了一个类模板,其中包含一些运算符重载函数,用于添加和删除元素。当我在int,double和char专门化上测试加法和减法重载方法时,程序完美地添加和删除了元素(没有核心转储);然而,当在字符串上尝试这个时,我得到一个核心转储。我确保使用#include <string>
并使用std :: string。任何人都可以解释为什么这适用于int,double和char特化,但不适用于字符串?
template <class T> T Set<T>::iVal;
template <class T> T Set<T>::DELIM;
template <class T>
//
//default constructor
//
Set<T>::Set ( int s ){
psize = ( s > 0 ? s: DEFAULTSIZE);
//allocate an array of specified size
set = new T[ psize ];
if(!set) {
//send an error is system cannot allocate memory
cout << "Cannot Allocate Memory, exiting program... " << endl;
exit (1);
}
for ( int i = 0; i < psize; i++){
set[i] = iVal;
}
numOfElements = 0;
}
//
//custom constructor
//
template <class T>
Set<T>::Set( T array[] , int size, char name ){
set = new T[size];
psize = ( size > 0 ? size: DEFAULTSIZE);
numOfElements = size;
for ( int i = 0; i < psize; i++){
set[i] = array[i];
}
if (!set){
cout << "Cannot Allocate Memory, exiting program... " << endl;
exit(1);
}
Set::name = name;
}
//
//subtraction operator that removes elements
//
template <class T>
bool Set<T>::operator-( T n ){
bool status = false;
for ( int i = 0; i < numOfElements; i++){
if ( set [i] == n ){
for ( int j = i; j < numOfElements; j++){
set [j] = set[j + 1];
}
set[numOfElements - 1] = n;
--numOfElements;
}
status = true;
}
return (status);
}
//
//addition operator that adds elements
//
template <class T>
bool Set<T>::operator+( T n ){
bool status = false;
if ( !element(n) ){
if ( psize == numOfElements ) {
T *ptr = new T[psize += 1];
for ( int i = 0; i < numOfElements; i++ )
ptr[i] = set[i];
delete [] set;
set = ptr;
psize += 1;
delete [] ptr;
}
set[numOfElements] = n;
numOfElements += 1;
status = true;
}
return status;
}
//In Driver
//
//Creating string arrays using the custom constructor to instantiate objects
//
string s1[4] = { "turtle" , "fish", "shark" , "lobster" };
string s2[3] = { "turtle", "book", "pencil" };
//
//Testing string specialization
//
cout << "\nTesting strings.\n" << endl;
Set <string> string1 ( s1, 4, 'A' );
Set <string> string2 ( s2, 3, 'B' );
//setting delimiter
Set <string>::setDELIM ("stop");
//
//testing the addition and subtraction of elements
//CORE DUMP HAPPENS HERE
string1 - "shark";
cout << "\nAfter removing an element from Set A, Set A = " << string1 << endl;
string1 + "dolphin";
cout << "\nAfter adding an element to Set A, Set A = " << string1 << endl;
答案 0 :(得分:2)
我看到一些问题都是未定义的行为。它与其他数据类型一起使用的事实可能仅仅是因为运气。
首先,让我们看一下您的-
方法:
if ( set [i] == n ){
for ( int j = i; j < numOfElements; j++){
set [j] = set[j + 1]; // <-- Access past last element in array
}
set[numOfElements - 1] = n;
--numOfElements;
}
上面的内部循环应该测试j < numOfElements - 1
。这样,set[j+1]
将不会查看数组末尾之后的元素(如果numOfElements
恰好与分配的大小相同)。
现在让我们看看你的+
方法:
T *ptr = new T[psize += 1];
for ( int i = 0; i < numOfElements; i++ )
ptr[i] = set[i];
delete [] set;
set = ptr;
psize += 1;
delete [] ptr; // <-- BOOM!
在上文中,您刚刚删除了set
,然后将其替换为ptr
指向的新内存。但后来你删除了那段记忆。如果删除标记的行,这应该可以。