При освобождении памяти обнуляется исходная строка - C (СИ)

Узнай цену своей работы

Формулировка задачи:

Здравствуйте! Есть функция, в ней из строки удаляются пробелы (ну и еще кое-что, не суть) путем посимвольного копирования из исходной строки в результирующую всех непробелов. В начале функции под результирующую строку выделяется память, в конце результирующая строка копируется в исходную и память освобождается. Проблема в том, что при освобождении памяти (free(res) почему-то обнуляется исходная строка s. Перед вызовом free() res и s указывают на разные адреса.
int delGaps(char* s)
{
    char* res;
    int index, res_index=0, marker=0;
    if (!strcmp(s,""))
        return emptyExpression;
    res = (char*)malloc((strlen(s)+1)*sizeof(char));
    for (index=0;index<strlen(s);index++)
    {
        if (isspace(s[index]))
        {
            marker=1;
            continue;
        }
        else if (   (marker && (res_index>0) && isdigit(res[res_index-1]) && isdigit(s[index])) || 
                    (marker && (res_index>0) && isalpha(res[res_index-1]) && isalpha(s[index]))  )
        {
            free(res);
            return wrongExpression;
        }
        else 
        {
            res[res_index++]=s[index];
            marker=0;
        }
    }
    res[res_index]=0;
    strcpy(s,res);
    free(res);
    return 0;
}
В чем дело? Спасибо)

Решение задачи: «При освобождении памяти обнуляется исходная строка»

textual
Листинг программы
#include <stdio.h>
#include <string.h>
 
char * remove_some(char * str, const char * toRemove) {
    char * ptr = strpbrk(str, toRemove);
    
    while ( ptr ) {
        memmove(ptr, ptr + 1, strlen(ptr));
        ptr = strpbrk(ptr, toRemove);
    }
    
    return str;
}
 
int main(void) {
    const char * toRemove = " _-";
    char str[] = "bla bla-bla_";
    
    printf("Before: %s\n", str);
    printf("After: %s\n", remove_some(str, toRemove));
    
    return 0;
}

Объяснение кода листинга программы

  1. В функции remove_some первым делом ищется первое вхождение подстроки toRemove в строке str с помощью функции strpbrk.
  2. Если strpbrk вернула ненулевой указатель, то с помощью функции memmove символ, следующий за найденным, перемещается на позицию найденного, тем самым удаляя его из строки.
  3. После этого снова вызывается strpbrk для поиска следующего вхождения подстроки toRemove в измененной строке.
  4. Если strpbrk вернула ненулевой указатель, то предыдущий шаг повторяется.
  5. Если strpbrk вернула нулевой указатель, то все вхождения подстроки toRemove были успешно удалены.
  6. Функция возвращает исходную строку.
  7. В функции main создается строка str, содержащая bla bla-bla _-.
  8. Создается константная строка toRemove, содержащая _-.
  9. Вызывается функция remove_some с передачей строки str и константной строки toRemove.
  10. Выводится исходная строка.
  11. Выводится строка, возвращенная функцией remove_some.
  12. Программа возвращает 0, заканчивая свое выполнение.

ИИ поможет Вам:


  • решить любую задачу по программированию
  • объяснить код
  • расставить комментарии в коде
  • и т.д
Попробуйте бесплатно

Оцени полезность:

7   голосов , оценка 3.857 из 5
Похожие ответы