Что за ошибка?
От: valenok  
Дата: 10.07.03 09:09
Оценка:
Почему если выполнить как есть, то все нормально, а если убрать коммент., то выскакивает (при запуске Debug, хотя точек остановки нету)
"User breakpoint called from code at 0x...."
При запуске exe-debug версии выскакивает
DAMAGE: after Normal block.....

код:
    char* cr=new char[MAX_PATH];
//    strset(cr,0);
    strcpy(cr,"проверка");
    delete[] cr;

И еще:
Запускаем в Debug (или debug-версию)
Выскакивает
"Debug Assertion Failed! Program:.... File: wincore.cpp"
Если жать "Пропустить" — то все проходит дальше, Release версия работает без сообщений.
Re: Что за ошибка?
От: Федько Олег Россия  
Дата: 10.07.03 09:18
Оценка: 2 (1)
Здравствуйте, valenok, Вы писали:

V>Почему если выполнить как есть, то все нормально, а если убрать коммент., то выскакивает (при запуске Debug, хотя точек остановки нету)

V>"User breakpoint called from code at 0x...."
V>При запуске exe-debug версии выскакивает
V>DAMAGE: after Normal block.....

V>код:

V>
V>    char* cr=new char[MAX_PATH];
V>//    strset(cr,0);
V>    strcpy(cr,"проверка");
V>    delete[] cr;
V>

V>И еще:
V>Запускаем в Debug (или debug-версию)
V>Выскакивает
V>"Debug Assertion Failed! Program:.... File: wincore.cpp"
V>Если жать "Пропустить" — то все проходит дальше, Release версия работает без сообщений.

надо делать
memset(cr,0,MAX_PATH)
или
*cr = 0

делая strset(cr, 0) ты заполняешь 0 до ближаёшего '\0', а так как строку ты не инициализировал
то '\0' там может и не оказаться!
Re: Что за ошибка?
От: Аноним  
Дата: 10.07.03 09:21
Оценка:
Здравствуйте, valenok, Вы писали:

V>Почему если выполнить как есть, то все нормально, а если убрать коммент., то выскакивает (при запуске Debug, хотя точек остановки нету)

V>"User breakpoint called from code at 0x...."
V>При запуске exe-debug версии выскакивает
V>DAMAGE: after Normal block.....

V>код:

V>
V>    char* cr=new char[MAX_PATH];
V>//    strset(cr,0);
V>    strcpy(cr,"проверка");
V>    delete[] cr;
V>

V>И еще:
V>Запускаем в Debug (или debug-версию)
V>Выскакивает
V>"Debug Assertion Failed! Program:.... File: wincore.cpp"
V>Если жать "Пропустить" — то все проходит дальше, Release версия работает без сообщений.

strset работает со строками заканчивающими '\0', а привыделении памяти 0 нет. strset заполняет всё 0 пока не встретит 0, это скорее всего происходит в чужой памяти, вот из-за этого твоя ошибка
Re: Что за ошибка?
От: UnrealAlex Россия  
Дата: 10.07.03 09:22
Оценка:
Здравствуйте, valenok, Вы писали:

    char* cr = new char[MAX_PATH];
    if (cr)
    {
        *cr = '\0';
        strset(cr,0);
        strcpy(cr,"проверка");
        delete[] cr;
    }
Невозможное мы сделаем сегодня — чудо займет немного больше времени. /Аноним/
Re: Что за ошибка?
От: Bell Россия  
Дата: 10.07.03 09:23
Оценка:
Здравствуйте, valenok, Вы писали:

V>Почему если выполнить как есть, то все нормально, а если убрать коммент., то выскакивает (при запуске Debug, хотя точек остановки нету)

V>"User breakpoint called from code at 0x...."
V>При запуске exe-debug версии выскакивает
V>DAMAGE: after Normal block.....

V>код:

V>
V>    char* cr=new char[MAX_PATH];
V>//    strset(cr,0);
V>    strcpy(cr,"проверка");
V>    delete[] cr;
V>


Загляни в MSDN и посмотри там описание setstr. Ты там увидишь, что первый параметр, это Null-terminated string to be set.



V>И еще:

V>Запускаем в Debug (или debug-версию)
V>Выскакивает
V>"Debug Assertion Failed! Program:.... File: wincore.cpp"
V>Если жать "Пропустить" — то все проходит дальше, Release версия работает без сообщений.

Ошибки работы с памятью — одни из самых неприятных, и главная неприятность в том, что симптомы могут быть самые различные, в том числе подобные ошибки могут вообще не проявляться до поры.
В общем либо надо быть либо очень внимательным, либо пользоваться std::string для работы со строками, и при этом все равно быть внмательным , поскольку невнимательный программист — это не есть хорошо.
Любите книгу — источник знаний (с) М.Горький
Re: Что за ошибка?
От: J.J.OK  
Дата: 10.07.03 09:23
Оценка: 2 (1)
Здравствуйте, valenok, Вы писали:

V>Почему если выполнить как есть, то все нормально, а если убрать коммент., то выскакивает (при запуске Debug, хотя точек остановки нету)

V>"User breakpoint called from code at 0x...."
V>При запуске exe-debug версии выскакивает
V>DAMAGE: after Normal block.....

V>код:

V>
V>    char* cr=new char[MAX_PATH];
V>//    strset(cr,0);
V>    strcpy(cr,"проверка");
V>    delete[] cr;
V>

V>И еще:
V>Запускаем в Debug (или debug-версию)
V>Выскакивает
V>"Debug Assertion Failed! Program:.... File: wincore.cpp"
V>Если жать "Пропустить" — то все проходит дальше, Release версия работает без сообщений.

MSDN on strset:
...
...
Remarks
The _strset function sets all the characters of string to c (converted to char),
except the terminating null character. 
...


т.е. strset рассматривает твой cr как asciiZ строку и забивает нулями всю память пока не найдет конца строки —
и в дебаговом варианте такой запуск портит no-mans-land после выделенного буфера — смотри устройство дебаговой кучи.
А в релизе (с теми настройками проекта что ты выставил) нолик находится в пределах выделенной тобой памяти.

пользуй memset или просто *cr = 0;

Удачи
Чем безопаснеe — тем неудобнее ;-)
Re[2]: Что за ошибка?
От: UnrealAlex Россия  
Дата: 10.07.03 09:26
Оценка:
Здравствуйте, UnrealAlex, Вы писали:

Почему-то при посылке выдрилсь комментарии к коду
Пока посылал, тебе все объяснили См. ниже по топику...
Невозможное мы сделаем сегодня — чудо займет немного больше времени. /Аноним/
Re: Что за ошибка?
От: Кодт Россия  
Дата: 10.07.03 09:32
Оценка: 5 (2)
Здравствуйте, valenok, Вы писали:

V>Почему если выполнить как есть, то все нормально, а если убрать коммент., то выскакивает (при запуске Debug, хотя точек остановки нету)

V>
V>    char* cr=new char[MAX_PATH];
V>//    strset(cr,0);
V>    strcpy(cr,"проверка");
V>    delete[] cr;
V>


1. Суть ошибки:

strset() забивает нулями всю строку (а строки, как мы помним, должны заканчиваться нулем).
Где у нас нуль? А бог его ведает, мы же не установили его. Где-то за пределами MAX_PATH, раз начал ругаться.

2. Почему в debug и release ведет себя по-разному?

Во-первых, отладочная версия менеджера памяти забивает свежевыделенный блок особым мусором (байт 0xCD).
Во-вторых, strset может проверить указатель на принадлежность выделенным блокам, что и происходит.

В релизе память кучи изначально обнуляется, а в дальнейшем (при выделении/освобождении) с ней ничего не делают.
Так что при благоприятном стечении обстоятельств strset() обнаруживает строку нулевой длины и выходит, а при неблагоприятном — либо расстреляет следующий блок, либо уйдет за пределы сегмента и вызовет Access Violation.

3. Как лечить?

1) Поскольку ты немедленно присваиваешь строку, то нет нужды ее обнулять.
2) Если бы тебе нужно было не strcpy(), а, скажем, strcat() -- то достаточно обнулить первый символ: cr[0]=0;
3) Если же ты хочешь зачистить весь блок — то, на выбор:
// CRT
#include <memory.h>
memset(cr, 0, MAX_PATH*sizeof(char));

// WinAPI
#include <windows.h>
ZeroMemory(cr, MAX_PATH*sizeof(char));

// STL
#include <algorithm>
std::fill(cr, cr+MAX_PATH, 0); // (1)
std::fill_n(cr, MAX_PATH, 0);  // (2)
Перекуём баги на фичи!
Re[2]: Что за ошибка?
От: valenok  
Дата: 10.07.03 10:50
Оценка:
Всем спасибо за разъяснения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.