崩溃删除[]初始化的字符串

时间:2013-01-06 19:56:26

标签: c++ string initialization

修复了来自未初始化指针的错误。一个旧的bug仍然存在,如果我删除了mystring,它会在stringclass::alloc()崩溃,尽管我们可以在之前处理或显示它。它已被初始化,所以这次发生了什么?

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

1 个答案:

答案 0 :(得分:2)

你正在溢出一个缓冲区。

char * temp = new char[temp_size];

应该是

char * temp = new char[temp_size+1];

此外,您的类没有赋值运算符,因此赋值它将执行浅拷贝并导致双重删除。