В настоящее время я пишу небольшое приложение для повторного ознакомления с C (прошло некоторое время с тех пор, как я в последний раз писал что-либо), и, как и большинство людей, я столкнулся с проблемой распределения памяти, которую я не могу понять.
Код вращается вокруг настройки различных панелей, окон и связанных с ними заголовков. Именно с выделением памяти для строки заголовка у меня проблемы.
База представляет собой структуру, которая содержит:
struct TFB_PANEL
{
WINDOW *window;
char *title;
};
Это typedef'd в заголовочном файле как:
typedef struct TFB_PANEL TfbPanel;
В соответствующем файле C у меня есть следующий метод, который инициализирует массив TFB
фиксированного размера.
int tfb_init()
{
if (!_initialised) {
return -1;
}
int i;
for (i = 0; i < TYPE_MAX; i++) {
TFB[i] = malloc(sizeof(TfbPanel*));
TFB[i]->title = calloc((strlen(TYPES[i]) + 18), sizeof(char*));
switch(i)
{
case A:
sprintf(TFB[i]->title, " %s | r | h | s | t ", TYPES[i]);
break;
case B:
sprintf(TFB[i]->title, " f | %s | h | s | t ", TYPES[i]);
break;
case C:
sprintf(TFB[i]->title, " f | r | %s | s | t ", TYPES[i]);
break;
case D:
sprintf(TFB[i]->title, " f | r | h | %s | t ", TYPES[i]);
break;
case E:
sprintf(TFB[i]->title, " f | r | h | s | %s ", TYPES[i]);
break;
}
TFB[i]->window = tfb_create_window(i);
}
return 0;
}
Теперь ошибка возникает при инициализации C. A и B правильно установлены на длину 25 символов. C, с другой стороны, после инициализации должен содержать 24 символа, но вместо этого (изнутри tfb_create_window) я получаю
Program received signal EXC_BAD_ACCESS, Could not access memory
Reason: 13 at address 0x0000000000000000
0x00007fff930b9390 in strcmp()
Изучение стека показывает, что TFB[C] инициализируется правильно, но элемент заголовка — нет. Это содержит нулевой элемент, как будто я никогда не вызывал calloc.
Пожалуйста, может кто-нибудь объяснить, где я ошибаюсь или почему A и B инициализируются правильно, но C убивает приложение. Все шло прекрасно примерно до 6 утра этим утром, с тех пор все шло под откос.
Если это поможет, tfb_create_window
определяется вызовом _create_window
и вызовом tfb_get_title
следующим образом:
char *tfb_get_title(int type)
{
if (type >= TFB_MAX) {
return (char*)NULL;
}
return TFB[type]->title;
}
WINDOW *tfb_create_window(int type)
{
int height = ((LINES - WIN_OFFSET_Y) / 3);
char *title = tfb_get_title(type);
return _create_window(height, WIN_SIDEBAR_X, WIN_OFFSET_Y, 0, COLOUR_MAIN, title);
}
WINDOW *_create_window(int height, int width, int starty, int startx, int color, const char *title)
{
WINDOW *window;
window = newwin(height, width, starty, startx);
box(window, 0, 0);
mvwprintw(window, 0, 2, title);
wbkgd(window, COLOR_PAIR(color));
return window;
}
calloc((strlen(TYPES[i]) + 18), sizeof(char*))
. Это выделяет место для(strlen(TYPES[i]) + 18
char указателей, что, вероятно, в 4 или 8 раз больше памяти, чем вам действительно нужно. - person svk   schedule 14.09.2013strlen(TYPES[i]) + 18
, но я добавил множитель, пытаясь это исправить. Я также пытался просто использоватьmalloc(strlen(TYPES[i]) + 18)
, но безрезультатно. - person mplf   schedule 14.09.2013malloc(sizeof(TfbPanel*))
вместоmalloc(sizeof(TfbPanel))
? Кроме того, что такоеTFB[i]
? - person Uchia Itachi   schedule 14.09.2013TFB[i]
— это указатель на действительный блок памяти, который раньше работал нормально, пока я не добавил динамический заголовок. МассивTFB
определяется как:TfbPanel *TFB[TYPE_MAX]
- person mplf   schedule 14.09.2013TfbPanel
? - person Uchia Itachi   schedule 14.09.2013struct TfbPanel
, и я все еще вижу ту же проблему. - person mplf   schedule 14.09.2013sizeof(char*)
доsizeof(char)
? - person Uchia Itachi   schedule 14.09.2013