我正在尝试“初始化”我在班级声明中制作的数组,但我不知道我做错了什么。我知道当你将一个数组传递给一个函数时,它会衰减成一个指向第一个字符的指针。代码在我的第二个strcpy()行中断,但我不确定它是做错了(我对strcpy()的经验很少。)
我的代码如下:
class TestClass
{
public:
TestClass(char []);
~TestClass();
void Append(TestClass);
char* m_string;
};
TestClass::TestClass(char incstring[])
{
char currentChar = 'a';
int numOfChars = 0;
while (currentChar != '\0') {
currentChar = *(incstring + numOfChars);
numOfChars++;
}
char* tmp = new char[numOfChars-1];
strcpy(tmp, incstring);
strcpy(m_string, tmp);
}
我的int main()很简单:
int main(){
TestClass* test = new TestClass("Hello");
}
如果值得注意,numOfChars等于6,正确应该是。
抛出的异常是:“访问冲突写入位置0xCDCDCDCD。”
答案 0 :(得分:2)
在将数据从m_string
复制到tmp
之前,您没有为m_string
分配任何内存。这就是你崩溃的原因。 m_string
未指向有效的内存地址。
由于您已经分配了tmp
并且您不再使用它,因此您可以直接将tmp
指针指定给m_string
,而无需执行其他副本。
另请注意,您的while
循环正在重复strlen()
已经执行的操作,因此您应该只使用strlen()
。
试试这个:
TestClass::TestClass(char incstring[])
: m_string(new char[strlen(incstring)+1])
{
strcpy(m_string, incstring);
}
TestClass::~TestClass()
{
delete[] m_string;
}
可以使用strdup()
来简化(使用free()
代替delete[]
来解除分配):
TestClass::TestClass(char incstring[])
: m_string(strdup(incstring))
{
}
TestClass::~TestClass()
{
free(m_string);
}
话虽如此,你的main()
正在泄漏内存,因为你没有释放test
对象:
int main(){
TestClass* test = new TestClass("Hello");
//...
delete test; // <-- add this
}
或者简单地说:
int main(){
TestClass test("Hello");
}
最后,请务必在班级中实施Rule of Three。您正在管理在析构函数中释放的动态内存,因此在从其他m_string
值创建TestClass
值时,您还需要复制构造函数和复制赋值操作以确保TestClass
的完整性:
class TestClass
{
private:
char* m_string;
public:
TestClass(char *incstring = 0);
TestClass(const TestClass &src);
~TestClass();
void Append(const TestClass &str);
void Swap(TestClass &Other);
TestClass& operator=(const TestClass &lhs);
};
TestClass::TestClass(char *incstring)
: m_string(0)
{
if (incstring)
{
m_string = new char[strlen(incstring)+1];
strcpy(m_string, incstring);
}
}
TestClass::TestClass(const TestClass &src)
: m_string(0)
{
if (src.m_string)
{
m_string = new char[strlen(src.m_string)+1];
strcpy(m_string, src.m_string);
}
}
TestClass::~TestClass()
{
delete[] m_string;
}
void TestClass::Append(const TestClass &str)
{
if (str.m_string)
{
TestClass tmp;
tmp.m_string = new char[strlen(m_string)+strlen(str.m_string)+1];
strcpy(tmp.m_string, m_string);
strcat(tmp.m_string, str.m_string);
Swap(tmp);
}
}
void TestClass::Swap(TestClass &Other)
{
char *ptr = m_string;
m_string = Other.m_string;
Other.m_string = ptr;
}
TestClass& TestClass::operator=(const TestClass &lhs)
{
if (this != &lhs) {
TestClass(lhs).Swap(*this);
}
return *this;
}