c ++ новый сбой только в релизе (MSVS10) - PullRequest
0 голосов
/ 03 марта 2012

При запуске только исполняемого файла релиза (при запуске через Visual Studio проблем не возникает) моя программа падает. При использовании функции «присоединить к процессу» Visual Studio указывает на сбой в следующей функции:

World::blockmap World::newBlankBlockmap(int sideLen, int h){
    cout << "newBlankBlockmap side: "<<std::to_string((long long)sideLen) << endl;
    cout << "newBlankBlockmap height: "<<std::to_string((long long)h) << endl;
    short*** bm = new short**[sideLen];
    for(int i=0;i<sideLen;i++){
        bm[i] = new short*[h];
        for(int j=0;j<h;j++){
            bm[i][j] = new short[sideLen];
            for (int k = 0; k < sideLen ; k++)
            {
                bm[i][j][k] = blocks->getAIR_BLOCK();
            }
        }
    }
    return (blockmap)bm;
}

Который вызывается из дочернего класса ...

World::chunk* World_E::newChunkMap(World::floatmap north, World::floatmap east, World::floatmap south, World::floatmap west
,float lowlow, float highlow, float highhigh, float lowhigh, bool displaceSides){
    World::chunk* c = newChunk(World::CHUNK_SIZE+1,World::HEIGHT);

    for (int i = 0; i < World::CHUNK_SIZE ; i++)
    {
        for (int k = 0; k < World::CHUNK_SIZE ; k++)
        {
            c->bm[i][0][k] = blocks->getDUMMY_BLOCK();
        }
    }

    c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)floor((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();
    c->bm[(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1][1][(int)ceil((float)(World::CHUNK_SIZE+1)/2.0f)-1] = blocks->getSTONE_BLOCK();

    return c;

}

где ...

class World {
public: typedef short*** blockmap;
...

Линия, на которую указывает VS, это ...

short*** bm = new short**[sideLen];

Функция "прикрепить к процессу" stats Локальные переменные ... sideLen = 1911407648 h = 0 это то, чего я НЕ ожидал, но Cout выдает 9 и 30 соответственно, что и ожидалось.

Мне известно, что большинство проблем, связанных с "сбоями только в выпуске", связаны с неинициализированными переменными, однако я не вижу связанных с этим проблем.

Единственное сообщение об ошибке, которое я получаю ... Windows запустила точку останова в Blocks Project.exe. Это может быть связано с повреждением кучи

Я поставлен в тупик на этой проблеме, в чем ошибка? как лучше отладить исполняемый файл релиза?

Я могу выложить больше кода, если необходимо, однако, имейте в виду, что его много.

Спасибо заранее.

"И я не вижу, чтобы World :: newBlankBlockmap () вызывался из этого второго куска кода. - Майкл Барр", я забыл этот бит, вот, пожалуйста ...

World::chunk* World::newChunk(int side, int height){
cout << "newChunk side: "<<std::to_string((long long)side) << endl;
cout << "newChunk height: "<<std::to_string((long long)height) << endl;
chunk* ch = new chunk();
ch->bm = newBlankBlockmap(side,height);
ch->fm = newBlankFloatmap(side);
return ch;

}

где ...

struct chunk {
    blockmap bm;
    floatmap fm;
};

как определено в Мировом классе

Ответы [ 2 ]

2 голосов
/ 03 марта 2012

Чтобы повторить то, на что намекают комментарии: из того, что вы опубликовали, ваш код выглядит плохо структурированным. Конструкции с тройным указателем, такие как short***, практически невозможно отладить, и их следует избегать любой ценой. Полученное вами сообщение об ошибке повреждения кучи говорит о том, что у вас есть неправильный доступ к памяти где-то в вашем коде, который невозможно найти автоматически при текущей настройке.

Ваши единственные варианты на данный момент - либо копать весь ваш код вручную, пока вы не найдете ошибку, либо начать рефакторинг. Последнее может показаться более трудоемким сейчас, но этого не произойдет, если вы планируете работать с этим кодом в будущем.

Рассмотрим следующие возможные подсказки для рефакторинга:

  • Не используйте простые массивы для хранения значений. std::vector столь же эффективен и намного проще в отладке.
  • Избегайте простых new и delete. В современном C ++ с контейнерами STL и интеллектуальными указателями простое распределение памяти должно происходить только в очень редких исключительных случаях.
  • Всегда проверяйте дальность операций доступа к массиву. Если вы беспокоитесь о производительности, используйте утверждения, которые исчезают в сборках релиза, но убедитесь, что проверки есть, когда они вам нужны для отладки.
  • Моделирование трехмерных массивов в C ++ может быть сложным, поскольку operator[] предлагает поддержку только одномерных массивов. Хороший компромисс использует вместо этого operator(), который может принимать произвольное количество индексов.
  • Избегайте бросков в стиле C. Они могут быть очень непредсказуемыми. Используйте взамен C ++ static_cast, dynamic_cast и reinterpret_cast. Если вы обнаружите, что регулярно используете reinterpret_cast, возможно, вы где-то ошиблись в своем дизайне.
0 голосов
/ 03 марта 2012

В этой строке есть проблема short*** bm = new short**[sideLen];.Память выделена для sideLen элементов, но для строки присваивания bm[i][j][k] = blocks->getAIR_BLOCK(); требуется массив размером sideLen * sideLen * h.Чтобы устранить эту проблему, необходимо изменить 1-ю строку на short*** bm = new short**[sideLen * sideLen * h];.

...