При освобождении памяти обнуляется исходная строка - 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;
- }
Объяснение кода листинга программы
- В функции
remove_some
первым делом ищется первое вхождение подстрокиtoRemove
в строкеstr
с помощью функцииstrpbrk
. - Если
strpbrk
вернула ненулевой указатель, то с помощью функцииmemmove
символ, следующий за найденным, перемещается на позицию найденного, тем самым удаляя его из строки. - После этого снова вызывается
strpbrk
для поиска следующего вхождения подстрокиtoRemove
в измененной строке. - Если
strpbrk
вернула ненулевой указатель, то предыдущий шаг повторяется. - Если
strpbrk
вернула нулевой указатель, то все вхождения подстрокиtoRemove
были успешно удалены. - Функция возвращает исходную строку.
- В функции
main
создается строкаstr
, содержащаяbla bla-bla _-
. - Создается константная строка
toRemove
, содержащая_-
. - Вызывается функция
remove_some
с передачей строкиstr
и константной строкиtoRemove
. - Выводится исходная строка.
- Выводится строка, возвращенная функцией
remove_some
. - Программа возвращает 0, заканчивая свое выполнение.
ИИ поможет Вам:
- решить любую задачу по программированию
- объяснить код
- расставить комментарии в коде
- и т.д