При освобождении памяти обнуляется исходная строка - 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, заканчивая свое выполнение.