Сначала предисловие:
Пишу я программку одну, не важно, чего она там делает, главное, что в начале работы она всякую конфигурационную информацию из файлов считывает. Файлы текстовые и устроены однотипно - строки в виде <параметр>:<значение>. Я все это хозяйство в массивы запихиваю, состоящие из парных структур, ну, например typedef struct {char *id; char *value;} Потом массивы эти по первому полю сортирую, чтобы можно было быстренько бинарным поиском там что надо найти. Раньше я память выделял только для собственно строковой информации, а массивы заводил декларативно, закладываясь на некий теоретический максимум. А теперь вот подумал: а чего это я память зря трачу, буду я под массивы тоже память динамически выделять. Ну и сделал сначала с realloc'ом, я ж не знаю, сколько у меня там элементов будет. Не пошло что-то. Программа выполняла недопустимую операцию и бывала закрыта. Ладно, пусть 2 прохода будет - информацию-то один раз только при старте надо считать, скорость большого значения не имеет. Считываю файл, пробегаю его, строки считаю, выделяю память сразу под весь массив, потом следующим проходом его заполняю. А теперь проблема: В первый раз - все ОК, работает, как и задумано. А вот при попытке выделить память для второго массива - падает. Что характерно, падает только под win98, ХР и 2000-я спокойно все проглатывают. Но мне надо, чтобы и под 98-й работало. Всяко попробовал, функции там такие-секие, опции компилятора тоже... Теперь найденное решение: Если выделять памяти не столько, сколько элементов в массиве реально окажется, а на один больше, все нормально работает и под win98. И я так кумекаю, что можно и realloc ставить, если только изначально запросить на один элемент больше. Вопрос: Почему?! Если кто знает, разъясните, пожалуйста. |
Сишный компилятор чей? И версия какая? |
Borland C++ 5.5.1 из FreeCommandLineTools.
Это важно? Ведь я использую функции WinAPI, которые к компилятору не имеют отношения. IMHO, причина в механизмах выделения памяти. Может быть что-нибудь подскажет сообщение: Программа вызвала сбой при обращении к странице памяти в модуле KERNEL32.DLL по адресу 0187:bff7a125. Строчка, вызывающая ошибку: a=(gvIndex *)HeapAlloc(GetProcessHeap(),0,q*sizeof(gvIndex)); где q - честно подсчитанное количество будущих элементов, а gvIndex - это та самая структура из двух указателей (8 байт, я проверял). Соответственно, если вместо q написать q+1, все работает без ошибок. Гарантирую, что q вычислено правильно - это я в первую очередь проверил. К тому же на NT системах программа работает именно так, как ожидается. |
P.S.
Вместо HeapAlloc можно использовать LocalLock(LocalAlloc(...)) или malloc(), или calloc() - результат тот же. Хотя адрес в сообщении об ошибке вроде бы другой получается, не помню уже. Не пробовал VirtualAlloc - это немного из другой оперы, надо будет проверить. Неар'ы тоже пробовал разные брать - не помогает. |
moishe писал(а): a=(gvIndex *)HeapAlloc(GetProcessHeap(),0,q*sizeof(gvIndex));_________________ Ин дер гросен фамилие нихт клювен клац-клац |
Это привычка, не более. На конечном коде не сказывается. Функция возвращает указатель на void, а я как бы "привожу" его к указателю на структуру. Хотя такие указатели компилятору и приводить-то не надо, так что это чисто для себя. |
не понятно, с чего бы выдавать ошибку при выделении памяти, ибо какая разница - 40 байт или 50 выделить? _________________ Ин дер гросен фамилие нихт клювен клац-клац |
В том и фишка. Это явно не нехватка памяти - во-первых памяти еще полно, а во-вторых сам по себе отказ в выделении памяти не приводит к аварийному завершению процесса со стороны системы. К тому же первый раз память для массива выделяется, а второй раз - ошибка, хоть какого размера они будь, я разные комбинации пробовал.
Знал бы что там в KERNEL32 по адресу 0187:bff7a125 лежит, может и понял бы, почему ошибка. |
Это тем более странно, учитывая, что под строки память без проблем выделяется. Но я, правда, всегда для строки прошу на 1 байт больше, чем длина строки, чтобы нуль-терминатор туда записать. Такое впечатление, что массивам тоже некий терминатор нужен, причем только в 98-й почему-то. Сейчас попробую запросить не на 1 элемент, а на 1 байт больше... |
...работает! |
Ты знаешь, безсмысленно обсуждать, если нет перед глазами программы. У меня подозрение, что здесь элементарная алгоритмическая ошибка. |
мммм.... хы... _________________ Ин дер гросен фамилие нихт клювен клац-клац |
|
Вы не можете начинать темы Вы не можете отвечать на сообщения Вы не можете редактировать свои сообщения Вы не можете удалять свои сообщения Вы не можете голосовать в опросах Вы не можете вкладывать файлы Вы можете скачивать файлы |