Легенда:
новое сообщение
закрытая нитка
новое сообщение
в закрытой нитке
старое сообщение
|
- Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
- Новичкам также крайне полезно ознакомиться с данным документом.
[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
|
|
|
[C++] Ну блин, опять подземные стуки... 05.02.04 13:33
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
Напиши русским языком, что у тебя за структура, что за функция ее заполняет. Лучше, как уже не раз попросили - определение структуры (или хотя бы название, если она описана в MSDN) и раз системная функция - название функции. "Добавил не помню что, и перестало работать, а потом перенес на глобальный уровень и все заработало" - это стрельба по кустам. Можно спорить до посинения, почему оно заработало, если не знаешь, почему оно перестало работать.
|
|
Есть одно - мысль на него наводит тот факт, что перемещение... 05.02.04 12:44
Автор: SL Статус: Незарегистрированный пользователь
|
> Есть ли у кого-нить какие-нить соображения на этот счёт?? Есть одно - мысль на него наводит тот факт, что перемещение структуры из зоны видимости функции решило проблему.
Если ты объявяляешь переменные по ходу дела, т.е. не в начале функции, а где-то в середине кода, то компилятор патыется создать стек как можно меньшего размера (если это возможно), при этом некоторые переменные как бы используются не по назначению, а в новом качестве. Не исключено, что ввиду сложности твоей программы что-то где-то ввело компилятор в заблуждение и он загреб не то что нужно. Это конечно гипотеза, но всяк может быть - компилятор - штука сложная и некоторые эвристики зашитые в нем, могут в каких-то ситуациях неправильно сработать.
И есть еще одна широко распространенная ошибка - в строку пишется больше, чем объявлено и гадится стек или код...
А вообще-то надо точно знать, что ты добавил и куда, а не гадать по отрывкам...
|
| |
Вот, один грамотный ответ.
06.02.04 11:43
Автор: ih8u <i hate you> Статус: Member
|
Вот, один грамотный ответ.
В полне возможно что именно так. Действительно, переменные объявлены по ходу а не в начале.
|
| | |
Я сталкивался с глюками компиляторов C++. И вот что хочу сказать. 06.02.04 20:10
Автор: Ktirf <Æ Rusakov> Статус: Elderman
|
Если тебе хочется свалить на компилятор, можешь сваливать на него, но я не понимаю, зачем ты вообще тогда задал вопрос. И я совершенно согласен с Killer'ом: сколько себя помню, потенциальный глюк компилятора или библиотеки чаще всего оказывался моим глюком. И еще: ЧТО ЗА ФУНКЦИЯ, ЧТО ЗА СТРУКТУРА?! Тебя сколько раз и всколькером надо просить, чтобы ты о них рассказал?!
|
| | | |
Ну нате: 06.02.04 20:31
Автор: ih8u <i hate you> Статус: Member Отредактировано 06.02.04 20:40 Количество правок: 3
|
> И еще: ЧТО ЗА ФУНКЦИЯ, ЧТО ЗА > СТРУКТУРА?! Тебя сколько раз и всколькером надо просить, > чтобы ты о них рассказал?! Ну нате:
long l = 0;
RASENTRYNAME re[100];
DWORD cb, dwEntries;
for(l = 0; l < 100; l++)
re[l].dwSize = sizeof(RASENTRYNAME);
cb = sizeof(re);
RasEnumEntries(NULL, NULL, &re[0], &cb, &dwEntries);
if(dwEntries > 0)
{
for(l = 0; l < dwEntries; l++)
{
BOOL PwdDetected;
RASDIALPARAMS par;
DWORD Entrysz;
RASENTRY rasent;
ZeroMemory(&rasent, sizeof(RASENTRY));
rasent.dwSize = sizeof(RASENTRY);
Entrysz = sizeof(RASENTRY);
ZeroMemory(&par, sizeof(RASDIALPARAMS));
RasGetEntryProperties(NULL, re[l].szEntryName, &rasent, &Entrysz, NULL, NULL);
par.dwSize = sizeof(RASDIALPARAMS);
lstrcpy(par.zEntryName, re[l].szEntryName);
if(RasGetEntryDialParams(NULL, Params, &PwdDetected))
{
printf("no pass\r\n");
break;
}
else
{
if(PwdDetected)
{
printf("%s - %s - %s - %s - %s\r\n", par.szEntryName, rasent.szAreaCode, rasent.szLocalPhoneNumber, par.szUserName, par.szPassword);
}
}
}
}
всёравно тут всё правильно, дело не в этом коде
Если щас скомпилить, то всё должно работать, однако у меня перестало.
Нормальный код, всё делается как в MSDN писали.
|
| | | | |
Мы опять ушли в сторону... Где же код, который ошибку давал? 09.02.04 15:48
Автор: SL Статус: Незарегистрированный пользователь
|
Мне понравилась фраза
"Если щас скомпилить, то всё должно работать, однако у меня перестало"
Вот прокомментировал бы автор, что но этим имел в виду. И где же тот код, который ошибку давал? Ведь его именно все жаждут посмотреть!!!
|
| | | | |
Ага. Щазз. С синтаксическими то ошибками: 07.02.04 05:18
Автор: Killer{R} <Dmitry> Статус: Elderman Отредактировано 07.02.04 05:20 Количество правок: 1
|
> Если щас скомпилить, то всё должно работать, однако у меня > перестало. Ага. Щазз. С синтаксическими то ошибками:
было 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]; 07.02.04 02:01
Автор: + <Mikhail> Статус: Elderman Отредактировано 07.02.04 02:04 Количество правок: 1
|
кто тебя так научил: RASENTRYNAME re[100];
наверниака где-то ещё такя жа бодяга :)
P.S. а ты packing не трогал случаем
|
| | | | |
А че такое par.zEntryName? 07.02.04 01:44
Автор: whiletrue <Роман> Статус: Elderman Отредактировано 07.02.04 01:46 Количество правок: 1
|
> lstrcpy(par.zEntryName, re[l].szEntryName);
В RASDIALPARAMS есть только szEntryName
сорри, если тупой вопрос
|
| | | | |
а если под re выделять память динамически? 06.02.04 21:04
Автор: dl <Dmitry Leonov>
|
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
|
Я кстати попробвал выделить память динамически, вот как:
RASENTRYNAME *re, rs;
DWORD cb, dwEntries = 0, l = 0;
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 или тока под билдер?
|
|
|