Здравствуйте!
Пожалуйста, скажите где ошибка.
После запуска 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;
}
Почему вылетает?
Модераторы: Hawk, Romeo, Absurd, DeeJayC, WinMain
А почему бы не выделять при помощи new? Так сказать, в "красивом стиле" C++?
Не знаю, решит ли это проблему, но, вроде,ри разработке C++ приложений рекомендуют этими функциями пользоваться.
Не знаю, решит ли это проблему, но, вроде,ри разработке C++ приложений рекомендуют этими функциями пользоваться.
-
- Сообщения: 7
- Зарегистрирован: 27 окт 2007, 18:58
На Си вся программа и то, что она использует (.c и .h файлы для работы со строками, файлами и пр.). К стыду своему пишу на Си (уже долго), однако приходит осознанование того, что в Си не хватает некоторых возможностей, а в последнее время точно понял: надо С++. Недавно стал Си++ осваивать, а пока пишу на Си пользуясь старыми наработками (времени нехватает для С++ практики).BBB писал(а):А почему бы не выделять при помощи new? Так сказать, в "красивом стиле" C++?
Не знаю, решит ли это проблему, но, вроде,ри разработке C++ приложений рекомендуют этими функциями пользоваться.
- Romeo
- Сообщения: 3091
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Код: Выделить всё
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;
Второй вопрос почти риторический и сразу же укажет тебе на источник проблемы. Внимательно изучи этот фрагмент:
Код: Выделить всё
sizeof (table_string_t) * i+1
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
-
- Сообщения: 7
- Зарегистрирован: 27 окт 2007, 18:58
Прости, перед постом кода на форум я его изменил и урезал настолько, чтобы всякий мог у себя его откомпилировать. Для строки таблицы выделяеться память в N строк (ячеек), где N - количество колонок. У меня их 8, но может быть сколько угодно, поэтому память выделяю не сразу а по мере надобности (да и не хочется сразу, ведь должен же realloc работать, он у меня всегда работал).Romeo писал(а): Первый вопрос. Что ты хочешь добиться таким кодом? Зачем в цикле делать realloc, если можно один раз до цикла сделать malloc?
Ты прав, нужны скобки (это я перед постом ошибку допустил). Но и со скобками проблема остается. Чую, что где-то глупая ошибка, так бывает часто, но вот где... Эх!Romeo писал(а): Внимательно изучи этот фрагмент:
sizeof (table_string_t) * i+1
- Romeo
- Сообщения: 3091
- Зарегистрирован: 02 мар 2004, 17:25
- Откуда: Крым, Севастополь
- Контактная информация:
Попробуй realloc заменить на malloc, memcpy, free. Если поможет, то бока в твоём коде. Если не поможет, то кривой компилер У меня других предложений пока нет.
Entites should not be multiplied beyond necessity @ William Occam
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
---
Для выделения С++ кода используйте конструкцию [ code=cpp ] Код [ /code ] (без пробелов)
---
Сообщение "Спасибо" малоинформативно. Благодарность правильнее высказать, воспользовавшись кнопкой "Reputation" в виде звёздочки, расположенной в левом нижнем углу рамки сообщения.
Ошибка многих начинающих программистов состоит в том, что они сразу начинают писать программный код, не продумав до конца архитектуру приложения. Из-за этого потом трудно бывает разобраться в их коде и найти в нём ошибку. Даже если ты выполняешь задачу не на С++, а на обычном Си, то всё равно тебе сначала нужно подумать, из каких сущностей будет состоять твоя программа и придумать целый набор функций для работы с ними. Ну например, если тебе нужно реализовать таблицу, то тебе понадобятся примерно такие функции:
CreateTable(), DestroyTable(),
InsertColumn(), DeleteColumn(),
AddRow(), DeleteRow(),
CreateCell(), DestroyCell(),
GetCellValue(), SetCellValue(), и др.
В этих функциях ты должен будешь использовать функции выделения/освобождения памяти, инициализацию массивов, и т.д. А уже в функции main() ты должен использовать свои функциональные заготовки. А если ты в одной функции main() непосредственно будешь писать циклы по выделению и освобождению памяти, то ты только запутаешь себя и других. Ничего хорошего из этого не получится.
CreateTable(), DestroyTable(),
InsertColumn(), DeleteColumn(),
AddRow(), DeleteRow(),
CreateCell(), DestroyCell(),
GetCellValue(), SetCellValue(), и др.
В этих функциях ты должен будешь использовать функции выделения/освобождения памяти, инициализацию массивов, и т.д. А уже в функции main() ты должен использовать свои функциональные заготовки. А если ты в одной функции main() непосредственно будешь писать циклы по выделению и освобождению памяти, то ты только запутаешь себя и других. Ничего хорошего из этого не получится.
-
- Сообщения: 7
- Зарегистрирован: 27 окт 2007, 18:58
Код в мойм вопросе лишь для того, чтобы продемонстрировать проблему. Вытащил из порядочного места, вставил в main() и он оставил свою проблемоспособность.WinMain писал(а):Ошибка многих начинающих программистов состоит в том, что они сразу начинают писать программный код, не продумав до конца архитектуру приложения. Из-за этого потом трудно бывает разобраться в их коде и найти в нём
-
- Сообщения: 7
- Зарегистрирован: 27 окт 2007, 18:58
Ошибка найдена. Тип должен быть (strtext_t *), а не (table_string_t*). Это не я нашел, а хороший человек на форуме ином.