strcat создает аварийную программу (0xc0000005)
Мне нужно нарисовать линию символов так долго, как я хочу. Поэтому я написал функцию для этой цели:
void fDrawLine(int length)
{
int i;
char * compLine = (char *) malloc(WINDOW_WIDTH + 2);
for(i = 0; i < length; i++)
strcat(compLine, "-");
fDrawSpacedMessage(compLine, -1, TRUE);
}
WINDOW_WIDTH
определяется как 80
, fDrawSpacedMessage
это еще одна функция для печати текстов по центру и т. д.
Он отлично строится, без ошибок, без предупреждений. Но во время выполнения все работает, но если fDrawLine
выполняется, программа вылетает и выдает код ошибки 0xc0000005
, Я знаю, что это о распределении памяти, но я уже инициализирую compLine
строка.
Я попробовал пару вещей; Я думал, что другая функция вызвала это, поэтому я изолировал fDrawLine
, но сбой продолжился. Изменение инициализации с compLine[0] = 0;
, compLine[WINDOW_WIDTH] = {0};
не помогло.
Он хорошо работает с моей другой машиной, на которой работает Ubuntu, с последней версией gcc, но при использовании Code::Blocks (MinGW) в Windows происходит сбой.
Что не так с этим кодом?
3 ответа
Выделенная память начинает содержать мусор. Установите его в пустую строку, например, так:
compLine[0] = '\0';
Не объявляй compLine
в качестве указателя, так как вам это не нужно, и на самом деле у вас утечка памяти в вашей функции, сначала объявите compLine
сюда
char compLine[1 + WINDOW_WIDTH] = {0}; // strings need an extra byte at the end to mark the end.
затем используйте memset
установить '-'
такой персонаж
memset(compLine, '-', length);
конечно, проверь что length <= WINDOW_WIDTH
,
Это ваша функция исправлена, так что вы можете попробовать ее
void fDrawLine(int length)
{
char compLine[1 + WINDOW_WIDTH] = {0}; // initialized so that last byte is '\0'.
if (length > WINDOW_WIDTH)
length = WINDOW_WIDTH;
memset(compLine, '-', length);
fDrawSpacedMessage(compLine, -1, TRUE);
}
помимо использования strcat
это плохая идея, вы можете сделать это так
char *compLine = malloc(1 + length); // the last extra '\0' byte.
if (compLine == NULL) // malloc returns NULL on failure to allocate memory
return; // so we must abort this function in that case.
for(i = 0; i < length; i++)
compLine[i] = '-';
compLine[length] = '\0';
fDrawSpacedMessage(compLine, -1, TRUE);
free(compLine);
Вы также можете использовать memset
в этом случае и это на самом деле лучше.
Ниже приведено несколько проблем с вашим кодом
void fDrawLine(int length)
{
int i;
char * compLine = (char *) malloc(WINDOW_WIDTH + 2);
for(i = 0; i < length; i++)
strcat(compLine, "-");
fDrawSpacedMessage(compLine, -1, TRUE);
}
Во-первых, length
параметр должен быть как минимум unsigned int
как отрицательная длина не имеет смысла. В идеале, вы должны использовать size_t
, То же самое касается i
,
Далее, вы не защищаете себя от недопустимых значений для length
, Неявный контракт заключается в том, что 0 <= length
<= WINDOW_WIDTH
- сделать это явным.
Использование динамически выделяемой памяти приводит к утечке памяти, так как вы не освобождаете ее после вызова fDrawSpacedMessage()
,
В заключение, strcat
излишне добавлять один символ.
Собирая все это вместе, вот альтернативная реализация.
void fDrawLine(size_t length)
{
size_t actual_length = length <= WINDOW_WIDTH ? length : WINDOW_WIDTH;
char compLine[WINDOW_WIDTH+2];
memset(compLine, '-', actual_length);
compline[actual_length] = '\0';
fDrawSpacedMessage(compLine, -1, TRUE);
}
Я ушел compline
в WINDOW_WIDTH+2
как я догадываюсь fDrawSpacedMessage
добавляет новую строку.
Если это все еще падает, проблема в fDrawSpacedMessage