我正在尝试动态地将内存分配给堆,然后删除分配的内存。下面的代码让我很难过:
// String.cpp
#include "String.h"
String::String() {}
String::String(char* source)
{
this->Size = this->GetSize(source);
this->CharArray = new char[this->Size + 1];
int i = 0;
for (; i < this->Size; i++) this->CharArray[i] = source[i];
this->CharArray[i] = '\0';
}
int String::GetSize(const char * source)
{
int i = 0;
for (; source[i] != '\0'; i++);
return i;
}
String::~String()
{
delete[] this->CharArray;
}
以下是编译器尝试删除CharArray时出现的错误:
0xC0000005:访问冲突读取位置0xccccccc0。
这是堆栈上的最后一次调用:
msvcr100d.dll!operator delete(void * pUserData)第52行+ 0x3字节C ++
我很确定这段代码中存在错误,但会为您提供所需的任何其他信息。哦,是的,使用VS 2010 for XP。
编辑:继承我的String.h
// String.h - string class
#pragma once
#define NOT_FOUND -1
class String
{
public:
String();
String(char* source);
static int GetSize(const char * source);
int Find(const char* aChar, int startPosition = 0);
~String();
private:
char* CharArray;
int Size;
};
答案 0 :(得分:5)
更改您的默认ctor;鉴于你得到的错误,删除调用试图删除一个从未初始化的指针。
String::String() : Size(0), CharArray(NULL) {}
另外,要注意“复制构造函数”。您可能希望将其设为私有,以确保您不会隐式触发它。 (如果你不打算调用它,就不需要实现它,只需将函数原型粘贴到类定义中。)同样可以“禁用”赋值运算符。
class String
{
// other stuff
private:
String(String&);
String& operator=(String&);
};
这个添加实现了“三个规则”,它表示如果任何类需要析构函数,复制构造函数或赋值运算符,它可能需要全部三个。
修改:请参阅http://en.wikipedia.org/wiki/Rule_of_three_%28C%2B%2B_programming%29
答案 1 :(得分:2)
String::String(): CharArray( 0 ) {}
您没有在每个构造函数中初始化CharArray
,因此在某些情况下您正在删除未初始化的指针。
答案 2 :(得分:0)
我认为@ dash-tom-bang是正确的。您可能正在复制String
,然后两次删除其数据。不过,我会在这里保留旧答案以供参考。
您需要发布使用String
的代码,但我可以在这里注意到一些问题:
如果构造函数中source
为NULL,该怎么办?你有一个空指针异常。更糟糕的是,如果你得到这个异常,析构函数将尝试删除从未分配的内存。如果您使用try
... catch
,这可能会导致上述错误。
GetSize
不应该是String
的成员函数,因为它不使用任何成员变量。至少它应该是static
。
答案 3 :(得分:0)
您有多个构造函数,但只有一个构造函数调用new。你的析构函数总是调用delete,所以你的错误。