повреждение кучи обнаружено после нормального блока (# 174)

я знаю, что этот вопрос был задан, но я не мог исправить свою программу

  void swap1(char*str1,char*str2)
{
    char *ezer =new char[strlen(str1)];
    for (int i = 0 ; i <= strlen(str1);i++)
        ezer[i]=str1[i];
    delete [] str1;
    str1= new char[strlen(str2)];
    for (int i = 0 ; i <= strlen(str2);i++)
        str1[i]=str2[i];
    delete [] str2;
    str2= new char[strlen(ezer)];
    for (int i = 0 ; i <= strlen(ezer);i++)
        str2[i]=ezer[i];
    delete[] ezer;
}

один раз в первый раз работает летучая мышь во 2-й (с другим значением) раз я получаю сообщение об ошибке ошибка появилась в последней строке delete[] ezer; почему я не могу удалить ezer?

Ошибка:

heap corruption detected after normal block (#174) at 0x007D7A48
CRT detected that the application wrote to memory end of heap buffer

person avi karbol    schedule 01.03.2013    source источник
comment
Просто предложение: возможно, вам следует добавить в следующий раз язык программирования, который вы используете в своем тексте и в качестве тега.   -  person sabisabi    schedule 01.03.2013
comment
Для тех, кто придет к этому позже, имейте в виду, что вы должны использовать std::string и std::swap для достижения такого поведения; это будет более эффективно, хотя и немного отличается.   -  person Alex Chamberlain    schedule 01.03.2013


Ответы (2)


strlen не считает нулевой терминатор в конце ваших строк. Это означает, что после одного применения вашей функции подкачки две строки будут заменены местами, но больше не будут заканчиваться нулем. Поведение strlen в строке без ограничителя null не определено, что означает, что вы работаете за пределами выделенной кучи, когда вы проходите одну из этих разделенных строк.

Строки в C представлены в виде указателя на символ с байтом с нулевым значением, указывающим на конец строки (упомянутый мной нулевой терминатор). Любая библиотечная подпрограмма, работающая со «строками», ожидает, что будет предоставлен массив символов с концом, отмеченным нулем, и в противном случае будет иметь неопределенное поведение (поскольку в этот момент вы предоставите массив символов, а не строку).

Используйте библиотечную функцию strcpy вместо создания собственной.

См. этот вопрос для получения подробной информации.

person Ron Dahlgren    schedule 01.03.2013
comment
Спасибо очень помогли мне Как я этого не заметил - person avi karbol; 01.03.2013

Вам не хватает места для 0-терминатора здесь:

char *ezer = new char[strlen(str1)];

Измените это на:

char *ezer = new char[strlen(str1) + 1];

Фактическое (первое) повреждение памяти происходит здесь:

  for (int i = 0 ; i <= strlen(str1);i++)
    ezer[i]=str1[i];

Как и в последней итерации (та, которая копирует 0-терминатор), ezer[i] относится к памяти "сразу за" тем, что было выделено для ezer.

Повторите то же самое для двух других выделений массива символов c.

В любом случае, поскольку это устранит повреждение кучи, функция не будет вести себя должным образом. Но это уже другая история... не так ли? ;-)

person alk    schedule 01.03.2013