Почему ошибка «malloc (): поврежденный верхний размер» исправлена, если у меня есть printf () до / после нее? - PullRequest
1 голос
/ 02 июля 2019

Учитывая абсолютный путь, я пытаюсь получить часть, которая идет после определенного каталога.Функция getTargetPath делает это, и когда я компилирую и запускаю приведенный ниже код, код дает мне ожидаемый результат.

Проблема в том, что когда я удаляю printf("\n") перед строкой с malloc в основном, я получаю:

malloc (): поврежденный размер топа
Прервано (ядро сброшено)

Поэтому, когда я ставлю printf("\n") до или после строки с malloc, код, кажется, работает нормально, но когда я удаляю его, я получаю ошибку выше.

Мой вопрос: почему это происходит?Я не прошу решение моей проблемы со строкой пути.Я просто хочу узнать, что вызывает такое поведение.

#include <stdio.h>
#include <string.h>
#include <stdlib.h>


const char* getTargetPath(const char* source)
{
    int count = 0;
    int i = 0;

    while(*source)
    {
        if (*source == '/')
        {
            ++count;
            if (count == 4)
            {
                break;
            }
        }
        ++source;
    }

    return source;
}


int main()
{
    const char* backup_path = "/home/ofy/real_2";
    char temp1[] = "/home/dir1/dir2/dir3/dir4/dir5";
    const char* s1 = temp1;

    const char* s2 = getTargetPath(s1);

    printf("\n");
    char* full_path = (char*)malloc(strlen(backup_path) * sizeof(char));

    strcpy(full_path, backup_path);
    strcat(full_path, s2);

    printf("%s\n", full_path);

    return 0;
}

1 Ответ

1 голос
/ 02 июля 2019

Вы не выделяете достаточно места для full_path:

char* full_path = (char*)malloc(strlen(backup_path) * sizeof(char));

Это должно быть как минимум столько же, сколько backup_path и s2, плюс 1 для завершающего нулевого байта, но вам достаточно только для backup_path. Это приводит к тому, что вы пишете после конца выделенной памяти, что вызывает неопределенное поведение .

С неопределенным поведением вы не можете предсказать, что будет делать ваша программа. Это может привести к сбою, может привести к странным результатам или может работать должным образом. Кроме того, внесение, казалось бы, несвязанного изменения кода может изменить то, как проявляется UB. Это именно то, что вы видели, когда убрали вызов printf. С printf программа «работала», в то время как без нее она зависала.

Чтобы выделить необходимое количество места:

char* full_path = (char*)malloc(strlen(backup_path) + strlen(s2) + 1);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...