0

私のクラスにはメモリの問題があります。この問題は、クラスのメンバー関数でオブジェクトを作成すると発生します。以下のクラスについてです。メンバー関数は必要ないため削除しました。

class User
{
private:
    bool locked;
    bool active;

    std::vector<City> * userCitys;
    UserData userData;
    Credentials credentials;

この関数を呼び出すと、問題が発生します。

int User::addCity(CityData cityData) 
{
    lockUserObject(); //Everything is fine here

    City cityToAdd; //When this object is created, the memory of userCitys will get overridden
    cityToAdd.activate();
    userCitys->push_back(cityToAdd);
    int cityID = userCitys->size() - 1;

    userCitys->at(cityID).editCityData(cityData);

    unlockUserObject();
    return cityID;
}

まず、スタックに userCity を作成しました。テスト目的で、ヒープに配置しました。userCity のアドレスは、一部のデータによって上書きされます。問題が見つかりません。City は単なる基本クラスです。

ヘッダーの一部:

class City
{
private:
    bool active;
    Supplies supplies;
    std::vector<Building> buildings;
    std::vector<Company> companies;
    std::vector<Share> shares;
    std::vector<Troop> troops;
    CityData cityData;

コンストラクタ:

City::City()
{
    active = false; 
}

userCity がオーバーライドされる可能性はどのようにあるのでしょうか? これはすべて単一のスレッドで発生するため、問題になることはありません。いろいろやってみたのですが、うまくいきません。問題を見つけるための最良のアプローチは何ですか?

編集: ロック機能:

void User::lockUserObject()
{
    for( int i = 0; locked ; i++)
    {
        crossSleep(Settings::userLockSleepInterval);

        if( i >= Settings::userLockMaxTimes )
            Error::addError("User lock is over userLockMaxTimes",2);
    }

    locked = true;
}

ここでコードを呼び出します (テスト関数):

City * addCity(User * user)
{
    Location location;
    location.x = 0;
    location.y = 1;

    CityData citydata;
    citydata.location = location;
    citydata.villagers = 0;
    citydata.cityName = "test city";

    int cityID = user->addCity(citydata); //addCity is called here
    City * city = user->cityAction(cityID);;

    if( city == NULL)
        Error::addError("Could not create a city",2);

    return city;
}

ユーザーの追加 (テスト コード):

User * addUser()
{
    UserData test;
    test.name = "testtest";
    Credentials testc("testtest",3);

    //Create object user
    int userID = UserControle::addUser(test,testc);
    User * user = UserControle::UserAction(userID);

    if( user == NULL)
        Error::addError("Could not create a user",2);

    return user;
}

私のテスト機能:

void testCode()
{
    User * user = addUser();
    City * city = addCity(user);
}

この関数はメインで呼び出されます:

int main()
{
    testCode();
    return 0;
}

UserControle の UserAction と addUser は次のとおりです。

int UserControle::addUser(UserData userdata, Credentials credentials)
{
    int insertID = -1;
    for( int i = 0; i < (int)UserControle::users.size(); i++)
    {
        if( !UserControle::users.at(i).isActive() )
        {
            insertID = i;
            break;
        }   
    }

    User userToInsert(userdata,credentials);

    if( insertID != -1 )
    {
        UserControle::users.insert( UserControle::users.begin() + insertID,userToInsert);
        return insertID;
    }
    else
    {
        UserControle::users.push_back(userToInsert);
        return UserControle::users.size() - 1;
    }
}

User* UserControle::UserAction(int userID) //check all indexes if greater then 0!
{
    if( (int)UserControle::users.size() <= userID )
    {
        Error::addError("UserAction is out of range",3);
        return NULL;
    }

    if( !UserControle::users.at(userID).isActive())
    {
        Error::addError("UserAction, the user is not active.",3);
        return NULL;
    }

    return &UserControle::users[userID];
}
4

1 に答える 1

1

あなたが試すことができるいくつかのことがあります:

  • 障害がなくなるまでコードを削除します。つまり、コードから最小限の例を抽出します。その後、自分でエラーが表示されると思いますが、そうでない場合は、その小さなサンプルプログラムをここに投稿してください。
  • 生のポインターを使用しないでください。それらの問題は常に、それらが指し示すものを誰が所有するかです。排他的所有権には、代わりに、unique_ptr (C++11) または auto_ptr (C++98) などのスマート ポインターを使用します。
  • 「userCities」のようなポインター メンバーがある場合、そのクラスのインスタンスをコピーするときに何が起こるかを考える必要があります (既に適切なデストラクタを作成していますか?)。そのため、コピーを防止する (コピー コンストラクターと代入演算子を非公開にし、実装せずに行う) か、ベクターが適切に複製され、異なるインスタンス間で共有されないように実装します。
  • C スタイルのキャストを使用しないでください。コンパイラを介して何かを取得するためにそれらが必要な場合、コードはおそらく壊れています。
于 2013-01-14T19:29:00.097 に答える