от
Я пытался написать строку заменить функцию на C, которая работает на
char *
, которая была выделена с помощью
malloc()
. Это немного отличается в том, что он будет найти и заменить строки, а не символы в исходной строке. Это тривиально, чтобы сделать, если поиск и замена строк одинаковой длины (или заменить на строку короче, чем строка поиска), так как у меня достаточно места выделено. Если я пытаюсь использовать
realloc()
, я получаю ошибку, которая говорит мне, что я делаю двойной бесплатно - что я не вижу, как я, так как я только через
realloc()
. Возможно, немного код поможет:
void strrep(char *input, char *search, char *replace) {
    int searchLen = strlen(search);
    int replaceLen = strlen(replace);
    int delta = replaceLen 

Программа работает, пока я пытаюсь realloc()
в случае, если замененная строка будет больше, чем исходная строка. (Она еще работает, она просто выплевывает ошибки, а также результат). Если это поможет, то вызывающий код выглядит как:
#include

Ваш ответ

Отображаемое имя (по желанию):
Конфиденциальность: Ваш электронный адрес будет использоваться только для отправки уведомлений.

9 Ответы

0 голосов
от
Я пытался написать строку заменить функцию на C, которая работает на
char *
, которая была выделена с помощью
malloc()
. Это немного отличается в том, что он будет найти и заменить строки, а не символы в исходной строке. Это тривиально, чтобы сделать, если поиск и замена строк одинаковой длины (или заменить на строку короче, чем строка поиска), так как у меня достаточно места выделено. Если я пытаюсь использовать
realloc()
, я получаю ошибку, которая говорит мне, что я делаю двойной бесплатно - что я не вижу, как я, так как я только через
realloc()
. Возможно, немного код поможет:
void strrep(char *input, char *search, char *replace) {
    int searchLen = strlen(search);
    int replaceLen = strlen(replace);
    int delta = replaceLen 

Программа работает, пока я пытаюсь realloc()
в случае, если замененная строка будет больше, чем исходная строка. (Она еще работает, она просто выплевывает ошибки, а также результат). Если это поможет, то вызывающий код выглядит как:
#include
0 голосов
от
Как правило, вы никогда не должны делать бесплатно или realloc на пользователей предоставленный буфер. Вы не знаете, где пользователю выделено пространство (в вашем модуле, в другой DLL), так что вы не можете использовать любые функции распределения на буфер пользователя. При условии, что вы сейчас не можете делать перераспределение внутри вашей функции, вы должны изменить свое поведение немного, как делала только одна замена, поэтому пользователь сможет вычислить результирующую строку максимальной длины и предоставить вам с буфером достаточно долго для этого одна замена произойдет. Затем вы можете создать еще одну функцию, чтобы сделать несколько замен, но вам придется выделить пространство для результирующей строки и скопировать в строку ввода пользователя. Затем вы должны предоставить способ, чтобы удалить строку, которую вы выделили. В результате:
void  strrep(char *input, char *search, char *replace);
char* strrepm(char *input, char *search, char *replace);
void  strrepmfree(char *input);
0 голосов
от
Во-первых, жаль, что я опоздал на вечеринку. Это моя первая ответе на StackOverflow. :) Как уже отмечалось, когда realloc() вызывается, вы можете изменить указатель на память перебрасываются. Когда это происходит, аргумент "строку" становится недействительным. Даже если переназначить его, изменение выходит из области видимости, когда функция заканчивается. Чтобы ответить на ОП, realloc() возвращает указатель на вновь перераспределить память. Возвращаемое значение нужно где-то хранить. Как правило, вы могли бы сделать это:
data *foo = malloc(SIZE * sizeof(data));
data *bar = realloc(foo, NEWSIZE * sizeof(data));

/* Test bar for safety before blowing away foo */
if (bar != NULL)
{
   foo = bar;
   bar = NULL;
}
else
{
   fprintf(stderr, "Crap. Memory error.\n");
   free(foo);
   exit(

Как TyBoer указывает, вы не можете изменить значение указателя, переданного в качестве входных данных для этой функции. Можно назначить что угодно, но выйдет из области видимости в конце функции. В следующем блоке "вход" может или не может быть недопустимый указатель, когда функция завершает:

void foobar(char *input, int newlength)
{
   /* Here, I ignore my own advice to save space. Check your return values! */
   input = realloc(input, newlength * sizeof(char));
}
Марк пытается обойти эту проблему, возвращая новый указатель в качестве результата функции. Если вы сделаете это, ответственность лежит на вызывающей стороны, чтобы никогда больше не использовать указатель, который он использовал для входа. Если он совпадает с возвращаемым значением, то у вас есть два указателя на одном и том же месте и нужно только позвонить бесплатно() на одном из них. Если они не совпадают, входной указатель теперь указывает на область памяти, которая может или не может быть владельцем процесса. Разыменование это может вызвать ошибку сегментации. Можно использовать двойной указатель для ввода, как это:
void foobar(char **input, int newlength)
{
   *input = realloc(*input, newlength * sizeof(char));
}
Если абонент имеет дубликатов входных указатель куда-то, что дубликат еще может быть недействительным. Я думаю, что наилучшим решением здесь является, чтобы избежать использования realloc() при попытке изменить входной функции абонента. Просто malloc() в новый буфер, вернуться, и пусть абонент решает, стоит ли бесплатно старый текст. Это имеет дополнительное преимущество, позволяя абоненту сохранить исходную строку!
0 голосов
от
Просто выстрел в темноте, потому что я еще не пробовал, но когда вы realloc возвращает указатель Муч такие как malloc. Потому что realloc может переместите указатель в случае необходимости вы, скорее всего, работающих на недопустимый указатель, если вы не сделаете следующее:
input = realloc(input, strlen(input)   delta);
0 голосов
от
Еще кто-то извинился за опоздание на партию - два с половиной месяца назад. Да ладно, я провожу довольно много времени, занимаясь археологией программного обеспечения. Мне интересно, что никто явно не прокомментировали утечку памяти в оригинальный дизайн, или на одну ошибку. И он наблюдал утечки памяти, что говорит мне, почему именно вы дважды без ошибок (потому что, если быть точным, вы не освобождая ту же память несколько раз - и вы делаете это после вытаптывания на уже освобожденной памяти). Прежде чем проводить анализ, я согласен с теми, кто говорит, что ваш интерфейс не столь выдающиеся, однако, если вы имеете дело с утечкой памяти вопросы/вытаптыванию и документально должны быть выделены требования к памяти, это может быть "ОК". Какие проблемы? Ну, вы передаете буфер realloc () и realloc() возвращает новый указатель на область, которую вы должны использовать - и вы игнорировать возвращаемое значение. Следовательно, realloc (), вероятно, освободил оригинальной памяти, и затем вы передаете его опять же указатель, и он жалуется, что ты освободив два раза одну и ту же память, потому что вы снова проходите первоначальное значение. Это не только утечки памяти, но это означает, что вы будете продолжать использовать оригинальный пространстве -- и выстрелил Джон Дауни в темноте указывает на то, что вы растратите realloc(), но не подчеркнуть, насколько сильно вы это делаете. Там же на одну ошибку, потому что вы не выделить достаточно места для нулевой символ '\0', который завершает строку. Утечка памяти происходит, потому что вы не обеспечивают механизм, чтобы сообщить абоненту о последнем значении строки. Потому что вы продолжали топтаться вокруг исходной строки плюс пробел после него, это выглядит как код работал, но если ваш код вызова уступил место, это тоже будет дважды без ошибок, или это может сделать дамп ядра или эквивалент, потому что в памяти управляющей информации полностью яичницей. Ваш код также не защищает от неограниченного роста -- рассмотреть вопрос о замене 'Ноэль' с 'Joyeux Ноэль. Каждый раз, вы хотели добавить 7 символов, но ты найдешь другого Ноэль в замене текста, и расширить его, и так далее, и так далее. Мои исправления (ниже) не решает эту проблему - самое простое решение, вероятно, чтобы проверить, является ли строка поиска отображается в строке замены; в качестве альтернативы можно пропустить строки замены и продолжить поиски. Второй имеет некоторые нетривиальные вопросы кодирования адреса. Итак, мое предложение по пересмотру вашего вызываемой функции:
char *strrep(char *input, char *search, char *replace) {
    int searchLen = strlen(search);
    int replaceLen = strlen(replace);
    int delta = replaceLen 

Этот код не обнаруживает ошибки выделения памяти, и, вероятно, падает (но если нет, утечки памяти), если realloc() завершается неудачей. Стив Магуайр 'запись книги твердый код на широкое обсуждение вопросов управления памятью.
0 голосов
от
Обратите внимание, попробуйте изменить ваш код, чтобы избавиться от коды HTML побег. Ну, хотя это было некоторое время, так как я использовал C и C , realloc, которое произрастает использует только значение указателя памяти, если есть место в памяти после того, как ваш исходный блок. Например, рассмотрим такую ситуацию: (ХХХХХХХХХХ..........) Если курсор указывает на первую X, и . значит, свободное место памяти, и вы увеличить размер памяти, на которую указывает переменная на 5 байт, то все получится. Это конечно упрощенный пример, как блоки округляются до определенного размера для выравнивания, но все равно. Однако, если впоследствии вы пытаетесь вырастить его еще на 10 байт, а там только 5 в наличии, его нужно будет переместить блок в памяти и обновить ваш указатель. Однако, в вашем примере вы передаете функции указатель на символ, а не указатель на переменную, и таким образом, хотя strrep функция внутренне может быть возможность корректировать переменной в использовании, он является локальной переменной в функции strrep и ваш вызывающий код останется исходный указатель переменной. Это значение указателя, однако, был освобожден. В вашем случае, входной сигнал является виновником. Однако, я хотел бы сделать одно предложение. В вашем случае это выглядит как ввод переменной действительно ввод, и если это так, он не должен быть изменен, на всех. Таким образом, я попытаюсь найти другой способ сделать то, что вы хотите сделать, не изменяя входного сигнала, в качестве побочных эффектов, как это может быть трудно отследить.
0 голосов
от
Это похоже на работу;
char *strrep(char *string, const char *search, const char *replace) {
    char *p = strstr(string, search);

    if (p) {
        int occurrence = p 

Вздохнув, все равно там постить код без него сосать?
0 голосов
от
realloc-это странно, сложно и должно использоваться только при работе с большим количеством памяти много раз в секунду. т. е. - где он на самом деле делает код быстрее. Я видел код, где
realloc(bytes, smallerSize);
был использован и работал, чтобы изменить размер буфера, делая его меньше. Работал около миллиона раз, потом почему-то realloc решил, что даже если бы Вы были сократить буфер, это даст вам хорошую новую копию. Так вы врежетесь в случайном месте 1/2 секунды после того, как плохое случилось. Всегда используйте возвращаемое значение realloc.
0 голосов
от
Мои быстрые подсказки. Вместо:
void strrep(char *input, char *search, char *replace)
попробуйте:
void strrep(char *
Добро пожаловать на сайт ByNets, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...