Страница 1 из 1
Почему вылетает?
Добавлено: 28 ноя 2007, 10:03
И.Владимир
Здравствуйте!
Пожалуйста, скажите где ошибка.
После запуска EXE - "вылетает", см. код ниже.
Компилятор - VC6, ОС - XP.
//
// Problem.c
//
#include <stdio.h>
#include <stdlib.h>
typedef struct
{ unsigned char* text;
unsigned long int len;//Количество символов в text, включая символ окончиня строки - '\0';
} strtext_t;
typedef struct
{ strtext_t *s;
} table_string_t; // Строка таблицы (строка ячеек).
typedef struct
{ unsigned char nc; // Количество колонок в таблице.
unsigned long int ns; // Количество строк в таблице.
table_string_t *sl; // Список табличных строк (кол-во = ns).
table_string_t c_name; // Строка таблицы. Названия колонок (кол-во = nc).
} table_t;
table_t tt;
int main()
{
char i;
tt.sl = NULL;
tt.c_name.s = NULL;
tt.nc = 0;
tt.ns = 0;
/* ХАРАКТЕР ПРОБЛЕМЫ
Если выделять память при помощи malloc - все нормально.
Если выделять и _изменять_ при помощи realloc и при этом еще что-то
записывать в tt.c_name.s[х].x - то происходит "вылет".
Если запись в tt.c_name.s[х].x производить как ниже, то вылетает на 6
"проходе" цикла, а если записывать более активно (выделять для .text память
и туда писать) - то вылетает уже на 3-ем проходе. */
for (i=0; i<8; i++)
{
tt.c_name.s = (table_string_t*) realloc (tt.c_name.s, sizeof (table_string_t) * i+1);
tt.c_name.s.text = NULL;
}
return 0;
}
Re: Почему вылетает?
Добавлено: 28 ноя 2007, 10:23
BBB
А почему бы не выделять при помощи new? Так сказать, в "красивом стиле" C++?
Не знаю, решит ли это проблему, но, вроде,ри разработке C++ приложений рекомендуют этими функциями пользоваться.
Re: Почему вылетает?
Добавлено: 28 ноя 2007, 10:45
И.Владимир
BBB писал(а):А почему бы не выделять при помощи new? Так сказать, в "красивом стиле" C++?
Не знаю, решит ли это проблему, но, вроде,ри разработке C++ приложений рекомендуют этими функциями пользоваться.
На Си вся программа и то, что она использует (.c и .h файлы для работы со строками, файлами и пр.). К стыду своему пишу на Си (уже долго), однако приходит осознанование того, что в Си не хватает некоторых возможностей, а в последнее время точно понял: надо С++. Недавно стал Си++ осваивать, а пока пишу на Си пользуясь старыми наработками (времени нехватает для С++ практики).
Re: Почему вылетает?
Добавлено: 29 ноя 2007, 11:27
Romeo
Код: Выделить всё
tt.c_name.s = (table_string_t*) realloc (tt.c_name.s, sizeof (table_string_t) * i+1);
tt.c_name.s[i].text = NULL;
Первый вопрос. Что ты хочешь добиться таким кодом? Зачем в цикле делать realloc, если можно один раз до цикла сделать malloc?
Второй вопрос почти риторический и сразу же укажет тебе на источник проблемы. Внимательно изучи этот фрагмент:
Как ты думаешь в каком порядке будет выполняться операции в этом выражении? Подсказка: операция
умножить имеет более высокий приоритет.
Re: Почему вылетает?
Добавлено: 29 ноя 2007, 12:18
И.Владимир
Romeo писал(а):
Первый вопрос. Что ты хочешь добиться таким кодом? Зачем в цикле делать realloc, если можно один раз до цикла сделать malloc?
Прости, перед постом кода на форум я его изменил и урезал настолько, чтобы всякий мог у себя его откомпилировать. Для строки таблицы выделяеться память в N строк (ячеек), где N - количество колонок. У меня их 8, но может быть сколько угодно, поэтому память выделяю не сразу а по мере надобности (да и не хочется сразу, ведь должен же realloc работать, он у меня всегда работал).
Romeo писал(а):
Внимательно изучи этот фрагмент:
sizeof (table_string_t) * i+1
Ты прав, нужны скобки (это я перед постом ошибку допустил). Но и со скобками проблема остается. Чую, что где-то глупая ошибка, так бывает часто, но вот где... Эх!
Re: Почему вылетает?
Добавлено: 29 ноя 2007, 13:03
Romeo
Попробуй realloc заменить на malloc, memcpy, free. Если поможет, то бока в твоём коде. Если не поможет, то кривой компилер
У меня других предложений пока нет.
Re: Почему вылетает?
Добавлено: 29 ноя 2007, 16:22
WinMain
Ошибка многих начинающих программистов состоит в том, что они сразу начинают писать программный код, не продумав до конца архитектуру приложения. Из-за этого потом трудно бывает разобраться в их коде и найти в нём ошибку. Даже если ты выполняешь задачу не на С++, а на обычном Си, то всё равно тебе сначала нужно подумать, из каких сущностей будет состоять твоя программа и придумать целый набор функций для работы с ними. Ну например, если тебе нужно реализовать таблицу, то тебе понадобятся примерно такие функции:
CreateTable(), DestroyTable(),
InsertColumn(), DeleteColumn(),
AddRow(), DeleteRow(),
CreateCell(), DestroyCell(),
GetCellValue(), SetCellValue(), и др.
В этих функциях ты должен будешь использовать функции выделения/освобождения памяти, инициализацию массивов, и т.д. А уже в функции main() ты должен использовать свои функциональные заготовки. А если ты в одной функции main() непосредственно будешь писать циклы по выделению и освобождению памяти, то ты только запутаешь себя и других. Ничего хорошего из этого не получится.
Re: Почему вылетает?
Добавлено: 29 ноя 2007, 17:23
И.Владимир
WinMain писал(а):Ошибка многих начинающих программистов состоит в том, что они сразу начинают писать программный код, не продумав до конца архитектуру приложения. Из-за этого потом трудно бывает разобраться в их коде и найти в нём
Код в мойм вопросе лишь для того, чтобы продемонстрировать проблему. Вытащил из порядочного места, вставил в main() и он оставил свою проблемоспособность.
Re: Почему вылетает?
Добавлено: 29 ноя 2007, 18:07
И.Владимир
Ошибка найдена. Тип должен быть (strtext_t *), а не (table_string_t*). Это не я нашел, а хороший человек на форуме ином.