初期化されていないポインターに起因するバグを修正した後。古いバグがまだ残っており、stringclass::alloc()
mystring を削除するとクラッシュしますが、直前に処理または表示できます。初期化されたのに今度はどうしたの?
void stringclass::alloc(long newsize)
{
if(memsize < newsize)
{
cout << "checkpoint 1\n";
if(mystring) delete [] mystring;
cout << "checkpoint 2\n";
memsize = newsize;
mystring = new char[memsize];
mystring[0] = 0;
length = 0;
}
}
完全なコード:
#include <iostream>
using namespace std;
#define DEFAULT_BREAKPOINT -1
#define DEFAULT_STARTPOINT -1
class stringclass
{
protected :
inline bool success() { failbit = false; return true; }
inline bool fail() { failbit = true; return false; }
public :
bool failbit;
long memsize;
long length;
char * mystring;
bool ins(const char * str, long startpoint, long breakpoint);
inline long get_length() { if(mystring) length = strlen(mystring); return length;}
inline long get_memsize() const { return memsize; }
void reset();
void alloc(long newsize);
void copy(const stringclass & other);
stringclass();
stringclass(const char str[]);
stringclass(const stringclass & other);
~stringclass();
friend ostream& operator << (ostream& out, stringclass & sc){out << sc.mystring; return out;}
};
void stringclass::copy(const stringclass & other)
{
if(other.mystring == NULL)
{
reset();
return;
}
alloc(other.memsize);
strcpy(mystring, other.mystring);
length = other.length;
}
stringclass::stringclass()
: mystring(NULL), memsize(0), length(0)
{
}
stringclass::stringclass(const char str[])
: mystring(NULL), memsize(0), length(0)
{
if(str != NULL)
{
alloc(strlen(str) + 1);
strcpy(mystring, str);
length = strlen(mystring);
}
}
stringclass::stringclass(const stringclass & other)
: mystring(NULL), memsize(0), length(0)
{
copy(other);
}
stringclass::~stringclass()
{
delete [] mystring;
}
void stringclass::reset()
{
if(mystring) delete [] mystring;
mystring = NULL;
length = 0;
memsize = 0;
}
void stringclass::alloc(long newsize)
{
if(memsize < newsize)
{
cout << "checkpoint 1\n";
if(mystring) delete [] mystring;
cout << "checkpoint 2\n";
memsize = newsize;
mystring = new char[memsize];
mystring[0] = 0;
length = 0;
}
}
bool stringclass::ins(const char * str, long startpoint = DEFAULT_STARTPOINT, long breakpoint = DEFAULT_BREAKPOINT)
{
if(startpoint == DEFAULT_STARTPOINT) startpoint = 0;
if(breakpoint == DEFAULT_BREAKPOINT) breakpoint = startpoint;
if(breakpoint > length || breakpoint - startpoint < 0) return fail();
if(str == NULL) return fail();
long str_length = strlen(str);
long temp_size = 0;
bool to_resize = false;
if(length + str_length + 1 - (breakpoint - startpoint) > memsize)
{
temp_size = (length + str_length + 1 - (breakpoint - startpoint));
to_resize = true;
}
else temp_size = memsize;
char * temp = new char[temp_size];
long temp_i = 0;
if(mystring) for(; temp_i < startpoint; temp_i++) temp[temp_i] = mystring[temp_i];
for(long str_i = 0; str_i < str_length; str_i++, temp_i++) temp[temp_i] = str[str_i];
if(mystring) for(long buf_i = breakpoint; buf_i < memsize; buf_i++, temp_i++)temp[temp_i] = mystring[buf_i];
temp[temp_i] = 0;
if(to_resize) alloc(temp_size); //empty
for(long buf_i = 0; buf_i < memsize; buf_i++) mystring[buf_i] = temp[buf_i];
if(temp) delete [] temp;
length = strlen(mystring);
return success();
}
int main()
{
stringclass str = "Hello";
str.ins("rld", str.get_length());
cout << str << endl;
str.ins(" the wo", 5);
cout << str << endl;
system("PAUSE");
return 0;
}