Повреждение кучи обнаружено после вызова удаления в Visual C ++?

0

Я пытаюсь запустить свой c++ код, введение которого в этот новый код привело к повреждению памяти, может ли кто-нибудь помочь мне в этом, что бы это вызвало. После вызова delete я столкнулся с этой проблемой. Я также попытался разместить newArgs[SZ] = '\0'; после каждого вызова strncpy.

Ошибка говорит:

КОПИРОВАНИЕ HEAP ОБНАРУЖЕНА после нормального блока (# 274) в 0X00C09600 и т.д.

int main(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* argc, int nShowCmd){

    MyClass *obj;
    char args[] = " hello world";
    int SZ = strlen(args);
    int argsLength = 0;

    if(argc != NULL)
        argsLength=strlen(argc);
    SZ+=argsLength;
    char *newArgs = new char[SZ];
    strncpy(newArgs, "",SZ);

    if(argc != NULL)
        strncpy(newArgs, argc,argsLength);

    StrCat(newArgs,args);

    obj = new MyClass(newArgs);
    delete[] newArgs;

    return 0; 
}
  • 1
    Какой SIZE ? Он используется, но никогда не объявляется.
  • 0
    Вы добавляете argsLength в SIZE не в SZ , поэтому newArgs не будет достаточно большим.
Показать ещё 4 комментария
Теги:
visual-c++
visual-studio-2010
heap-memory
heap-corruption

2 ответа

3

Вы извлекаете длину строки argc. Это без конечного нулевого байта:

argsLength=strlen(argc);

Позже вы копируете argc в свой буфер. Но вы копируете только символы argsLength, которые являются строкой без конечного нулевого байта. strncpy будет только копировать содержимое строки, а не добавлять конечный нулевой байт (см. man strncpy).

strncpy(newArgs, argc,argsLength);

Сразу же после strncpy вы добавляете другую строку в newArgs.

StrCat(newArgs,args);

В зависимости от содержимого newArgs после выделения (который может быть случайным, при отладке он, вероятно, будет заполнен специальным шаблоном) strcat fill не находит конечный нулевой байт в newArgs и, таким образом, будет читаться за пределами выделенного буфера (пока он не будет находит нулевой байт) и добавит ваши строковые аргументы там - где-то в куче и вне выделенной памяти. Это куча коррупции.

Кроме:

  1. При распределении памяти вам понадобится еще один байт для конечного нулевого байта.
  2. Какое использование strncpy (..., "", SZ)?
  3. Используйте std :: string, а не подверженные ошибкам строки C.
  4. Вы пропускаете выделенный объект MyClass.
  5. В C++ строковые литералы являются const.

Я бы переписал вашу программу таким образом (не компилировал и не тестировал ее):

int main(HINSTANCE hInstance, HINSTANCE hPrevInstance, char* argc, int nShowCmd)
{
    const char args[] = " hello world";
    std::string newArgs;
    if(argc != NULL)
        newArgs = argc;
    newArgs += args;

    // Use the line that you prefer
    MyClass obj1(newArgs.c_str());
    std::unique_ptr<MyClass> obj2(new MyClass(newArgs.c_str()));

    return 0; 
}
  • 0
    Как я могу получить длину argc и использовать это strncpy (..., "", SZ) для инициализации массива с пустыми символами изначально, так как он заполняет мусор по умолчанию.
  • 0
    длина аргумента argc: символы strlen (argc) плюс один завершающий нулевой байт. Таким образом, при объединении str1 и str2 целевой буфер должен иметь длину strlen (str1) + strlen (str2) +1 байт. strncpy (..., "", SZ) не будет копировать ни один байт (если SZ == 0), или только завершающий нулевой байт "" (если SZ> 0). Если вы хотите заполнить массив нулевыми байтами (в этом нет необходимости, потому что вы перезаписываете их позже), вам нужно использовать memset или std :: fill.
Показать ещё 2 комментария
0

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

Я настоятельно рекомендую вам остановить new char* в C++ и использовать strings.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню