всёравно тут всё правильно, дело не в этом коде
Если щас скомпилить, то всё должно работать, однако у меня перестало.
Нормальный код, всё делается как в MSDN писали.
[C++] Сможет мне кто-нить объяснить вот что..04.02.04 20:12 Автор: ih8u <i hate you> Статус: Member Отредактировано 04.02.04 20:20 Количество правок: 1
Вобщем делаю прогу, в которой есть большая функция, с кучей переменных и т.п. Сначала всё работало как часы. Но потом я ещо немного всякого добавил и тут произошоло то, что я никак не смог объяснить. Внезапно из структуры перестали выниматься данные (строковые) некоторых членов, в них был просто мусор, естественно при попытке сделать что-то типа sprintf или strcpy прога вылетала с ошибкой. Всё исравилось методом обнуления структуры, но как можно догадаться заместо мусора было ничего, тоесть ноль, естественно всё стало работать но с нулевыми данными.
Проблема решилась случайно, я решил члены этих структур сделать глобальными. Всё заработало. А я теперь голову ломаю, в чём было дело.
Есть ли у кого-нить какие-нить соображения на этот счёт??
[C++] Хватит гадать на кофеинои гуще, код в студию, а то модерить начнем05.02.04 21:29 Автор: + <Mikhail> Статус: Elderman
Напиши русским языком, что у тебя за структура, что за функция ее заполняет. Лучше, как уже не раз попросили - определение структуры (или хотя бы название, если она описана в MSDN) и раз системная функция - название функции. "Добавил не помню что, и перестало работать, а потом перенес на глобальный уровень и все заработало" - это стрельба по кустам. Можно спорить до посинения, почему оно заработало, если не знаешь, почему оно перестало работать.
Есть одно - мысль на него наводит тот факт, что перемещение...05.02.04 12:44 Автор: SL Статус: Незарегистрированный пользователь
> Есть ли у кого-нить какие-нить соображения на этот счёт?? Есть одно - мысль на него наводит тот факт, что перемещение структуры из зоны видимости функции решило проблему.
Если ты объявяляешь переменные по ходу дела, т.е. не в начале функции, а где-то в середине кода, то компилятор патыется создать стек как можно меньшего размера (если это возможно), при этом некоторые переменные как бы используются не по назначению, а в новом качестве. Не исключено, что ввиду сложности твоей программы что-то где-то ввело компилятор в заблуждение и он загреб не то что нужно. Это конечно гипотеза, но всяк может быть - компилятор - штука сложная и некоторые эвристики зашитые в нем, могут в каких-то ситуациях неправильно сработать.
И есть еще одна широко распространенная ошибка - в строку пишется больше, чем объявлено и гадится стек или код...
А вообще-то надо точно знать, что ты добавил и куда, а не гадать по отрывкам...
Вот, один грамотный ответ.
06.02.04 11:43 Автор: ih8u <i hate you> Статус: Member
Если тебе хочется свалить на компилятор, можешь сваливать на него, но я не понимаю, зачем ты вообще тогда задал вопрос. И я совершенно согласен с Killer'ом: сколько себя помню, потенциальный глюк компилятора или библиотеки чаще всего оказывался моим глюком. И еще: ЧТО ЗА ФУНКЦИЯ, ЧТО ЗА СТРУКТУРА?! Тебя сколько раз и всколькером надо просить, чтобы ты о них рассказал?!
Ну нате:06.02.04 20:31 Автор: ih8u <i hate you> Статус: Member Отредактировано 06.02.04 20:40 Количество правок: 3
всёравно тут всё правильно, дело не в этом коде
Если щас скомпилить, то всё должно работать, однако у меня перестало.
Нормальный код, всё делается как в MSDN писали.
Мы опять ушли в сторону... Где же код, который ошибку давал?09.02.04 15:48 Автор: SL Статус: Незарегистрированный пользователь
> Если щас скомпилить, то всё должно работать, однако у меня > перестало. Ага. Щазз. С синтаксическими то ошибками:
было lstrcpy(par.zEntryName, re[l].szEntryName); надо lstrcpy(par.szEntryName, re[l].szEntryName);
было RasGetEntryDialParams(NULL, Params, &PwdDetected) надо RasGetEntryDialParams(NULL, &par, &PwdDetected)
после того как я так поменял и откомпил оно мне все прекрасно выдало все мои диалап соединения. MSVC6.0 со всеми оптмизациями (не представляю где здеськ омпилер может заблудиться)
Замечание:
RasEnumEntries(NULL, NULL, &re[0], &cb, &dwEntries);
if(dwEntries > 0)
{
в хелпе не написано что в случае ошибки dwEntries устанавливается в 0. надо бы еще в объявлении сделать
DWORD cb, dwEntries=0;
ёпт, ну это тут я криво написал, так всё как ты исправил07.02.04 11:19 Автор: ih8u <i hate you> Статус: Member
RASENTRYNAME re[100] - это килобайт 30 на стеке. Если функция сильно вложенная, и по соседству такое же разбазаривание стека идет, его может просто не хватить.
Насколько я помню08.02.04 17:54 Автор: amirul <Serge> Статус: The Elderman
> RASENTRYNAME re[100] - это килобайт 30 на стеке. Если > функция сильно вложенная, и по соседству такое же > разбазаривание стека идет, его может просто не хватить. Stack Commit Size по умолчанию 0x2000 - 8 килобайт, а Stack Reserved Size - 0x100000 то бишь метр. Так что стека в третьем кольце достаточно :-)
Хотя совершенно согласен, что так относиться к стеку в серьезных программах - преступление :-)
но симптомы в общем-то подходящие08.02.04 19:45 Автор: dl <Dmitry Leonov>
Небольшие изменения в коде, приводящие к глюкам, перенос в статическую память, их исправляющий, нормальная работа в вырванном из программы коде. В первую очередь это, конечно, наводит на мысль о непроинициализированных значениях, но в коде с этой точки зрения все вроде бы чисто.
Размер стека в принципе мог быть и уменьшен, к тому же мы ведь не знаем, какие там еще массивы за углом создавались. Просто другого рационального объяснения я пока не вижу.
Я кстати попробвал выделить память динамически, вот как:
08.02.04 23:07 Автор: ih8u <i hate you> Статус: Member
cb = sizeof(RASENTRYNAME);
rs.dwSize = cb;
RasEnumEntries(NULL, NULL, &rs, &cb, &dwEntries);
// Вызываем RasEnumEntries что бы получит кол-во соединений
if(dwEntries > 0)
{
cb = (sizeof(RASENTRYNAME)*(dwEntries)); // Размер необходимой памяти
re = (RASENTRYNAME *)malloc(cb); // выделяем память
for(l = 0; l < dwEntries; l++)
re[l].dwSize = sizeof(RASENTRYNAME);
// Заполняем, хотя можно только первый элемент
RasEnumEntries(NULL, NULL, re, &cb, &dwEntries);
// Опять вызываем
for(l = 0; l < dwEntries; l++)
{
// Ну а дальше как обычно
}
if(re) free(re);
}
Вот, работает всё стабильно
Единственное, только не проверял как на старом коде, исправилось бы или нет, так как исправил всё. Вот надо ради эксперимента попробывать обраьтно всё вернуть и вот так исправить
Да, надо попробывать динамически выделить07.02.04 11:27 Автор: ih8u <i hate you> Статус: Member
> RASENTRYNAME re[100] - это килобайт 30 на стеке. Если > функция сильно вложенная, и по соседству такое же > разбазаривание стека идет, его может просто не хватить. Да, надо попробывать динамически выделить
всю жизнь объявлял переменные по ходу06.02.04 15:37 Автор: Killer{R} <Dmitry> Статус: Elderman
И еще ни разу не сталкивался с глюками компилятора (может мне везло?). Как правило после длительных разборок выяснялось что глючил всетаки я а не компилер. Вообще есть спец тулзы - для VC Bounds Checker для C++ билдера - встроенная фича под названием Code guard - я его всегда юзаю прежде чем делать релиз прог - отлавливает все большиснтво неверных и даже подозрительных обращений к памяти. В конце концов попробуй отключить все оптимизации. Да кстати - у тебя там в коде самой функции нету объвяленных здоровых массивов?
А можно поподробнее про эти тулзы? что это за Bounds checker...07.02.04 17:30 Автор: ih8u <i hate you> Статус: Member
> Вообще есть > спец тулзы - для VC Bounds Checker для C++ билдера - А можно поподробнее про эти тулзы? что это за Bounds checker и работает он под MSVC или тока под билдер?
Есть его версия и под MSVC08.02.04 15:15 Автор: Ktirf <Æ Rusakov> Статус: Elderman Отредактировано 08.02.04 15:17 Количество правок: 1