1

我正在尝试为堆动态分配内存,然后删除分配的内存。下面是让我很难受的代码:

// 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++

我相当肯定这段代码中存在错误,但会为您提供所需的任何其他信息。哦,是的,在 XP 上使用 VS 2010。

编辑:继承人我的 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;
};
4

4 回答 4

5

更改您的默认 ctor;鉴于您遇到的错误,delete 调用正在尝试删除从未初始化的指针。

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

于 2010-04-28T00:40:20.550 回答
2
String::String(): CharArray( 0 ) {}

您没有CharArray在每个构造函数中进行初始化,因此在某些情况下,您正在删除未初始化的指针。

于 2010-04-28T00:39:14.297 回答
0

我认为@dash-tom-bang 是正确的。您可能正在复制String并删除其数据两次。不过,我会在这里保留我的旧答案以供参考。

您将需要发布使用的代码String,但我可以在这里注意到一些问题:

  1. 如果source构造函数中为 NULL 怎么办?立即你有一个空指针异常。更糟糕的是,如果你得到这个异常,析构函数将尝试删除从未分配的内存。try如果您使用... ,这可能会导致上述错误catch

  2. GetSize不应该是成员函数,String因为它不使用任何成员变量。至少它应该是static

于 2010-04-28T00:39:09.523 回答
0

您有多个构造函数,但其​​中只有 1 个调用 new。你的析构函数总是调用 delete 所以你的错误。

于 2010-04-28T00:42:43.370 回答