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: ロケーション 0xcccccccc0 の読み取りアクセス違反。

そして、スタック上の最後の呼び出しは次のとおりです。

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

デフォルトのコンストラクターを変更します。発生しているエラーを考えると、delete呼び出しは、初期化されていないポインターを削除しようとしています。

String::String() : Size(0), CharArray(NULL) {}

また、「コピーコンストラクタ」にも注意してください。暗黙的にトリガーしないようにするために、プライベートにすることをお勧めします。(呼び出すつもりがない場合は実装する必要はありません。関数プロトタイプをクラス定義に貼り付けるだけです。)同様に、代入演算子を「無効」にすることもできます。

class String
{
   // other stuff

private:
    String(String&);
    String& operator=(String&);
};

この追加により、「三つのルール」が満たされます。つまり、クラスにデストラクタ、コピーコンストラクタ、または代入演算子が必要な場合は、おそらく3つすべてが必要です。

編集: 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、データを2回コピーしてから削除しています。ただし、参考のために古い回答をここに残しておきます。

を使用するコードを投稿する必要がありますがString、ここでいくつかの問題に気付くことができます。

  1. sourceコンストラクターでNULLの場合はどうなりますか?すぐにNullPointerExceptionが発生します。さらに悪いことに、この例外が発生した場合、デストラクタは割り当てられなかったメモリを削除しようとします。try...を使用している場合、これにより上記のエラーが発生する可能性がありますcatch

  2. GetSizeStringメンバー変数を使用しないため、のメンバー関数にすることはできません。少なくとも、そうする必要がありますstatic

于 2010-04-28T00:39:09.523 に答える
0

複数のコンストラクターがありますが、そのうちの1つだけがnewを呼び出します。デストラクタは常にdeleteを呼び出すため、エラーが発生します。

于 2010-04-28T00:42:43.370 に答える