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

Другие вопросы по тегам