2015-04-28 3 views
2

Это пахнет каким-то разломом кучи, но я не могу найти его. проблема возникает на string_utils_replace() при попытке запустить free(tmp_for_free). предполагается, что функция заменяет каждое вхождение "search" на "replace" в "string".Получение ошибки кучи при попытке освобождения

char* string_utils_part_of_string(char *string, int from, int to) 
{ 
    int size_to_allocate = to - from + 1; 
    char *result = (char*)malloc(sizeof(char) * size_to_allocate); 

    strncpy(result, string + from, to - from); 
    result[size_to_allocate - 1] = '\0'; 

    return result; 
} 

char* string_utils_replace(char *search, char *replace, char *string) 
{ 
    char *end, *result = string, *tmp_for_free = NULL; 
    int before_replace, after_replace; 
    int size_search = strlen(search); 
    int size_replace = strlen(replace); 
    int size_string, size_find; 
    int first_time = 1; 

    char *find = strstr(string, search); 

    if (find == NULL) 
     return string_utils_copy_string(string); 

    while (find != NULL) 
    { 
     tmp_for_free = result; 

     size_string = strlen(result); 
     size_find = strlen(find); 

     before_replace = size_string - size_find; 
     after_replace = before_replace + size_replace; 

     end = string_utils_part_of_string(result, after_replace, size_string); 
     result = string_utils_part_of_string(result, 0, before_replace); 
     strcat(result, replace); 
     strcat(result, end); 

     // no memory leaks, hooray! 
     free(end); 
     if (first_time == 0) 
      free(tmp_for_free); 

     size_string = strlen(result); 
     find = strstr(result, search); 
     first_time = 0; 
    } 

    return result; 
} 

любые идеи?

+1

проверяет, что «конец» не равен нулю, прежде чем освободить его – Morb

+0

первый цикл цикла «tmp_for_free = result;» присваивает неопределенное хранилище результатов для tmp_for_free .. – amdixon

+3

@Morb no, вам не нужно, 'free (NULL) 'отлично. –

ответ

3

Согласно man page из strcat(),

char *strcat(char *dest, const char *src);

[..] и строка Dest должен иметь достаточно места для результата. Если dest недостаточно велик, поведение программы непредсказуемо;

В вашей string_utils_part_of_string() функции, вы не выделить достаточно памяти для result, чтобы иметь возможность удерживать весь вход, а затем, вы пытаетесь использовать один и тот же указатель, чтобы сохранить весь вход , через strcat(). Это создает переполнение памяти, которое в свою очередь вызывает undefined behaviour.

Примечание: Пожалуйста, do not cast Возвращаемое значение malloc() и семья в C.

1

Вы вызывает переполнение буфера здесь:

result = string_utils_part_of_string(result, 0, before_replace); 
    strcat(result, replace); 
    strcat(result, end); 

result выделяется ровно before_replace+1 байт и инициализируется before_replace байт от начала string и окончательного '\0'. Вы не можете объединить replace и end в этот массив, он уже заполнен.

Логика в вашей функции свернута. Вы должны это упростить. Например, вы должны сначала запустить цикл, подсчитывающий количество вхождений find в string, затем распределить буфер для результата, затем запустить второй цикл копирования фрагментов string и копии replace.

Вы также должны проверить, является ли find пустой строкой. strstr() всегда найдет пустую строку, заставив ваш алгоритм бесконечно зацикливаться.

Смежные вопросы