我尝试写一串替代职能在C,其工作上 char *, ,这已经分配的使用 malloc().这是一个小小的不同之处在于,它将找到和替换串,而不是字在开始串。

这是微不足道该如搜索和替换串的长度是相同的(或者代替串短于检索字符串),由于我有足够的空间分配。如果我尝试使用 realloc(), 我得到一个错误,告诉我我在做一个双免费的-我怎么没看到我,因为我只是利用 realloc().

也许有点代码将有助于:

void strrep(char *input, char *search, char *replace) {
    int searchLen = strlen(search);
    int replaceLen = strlen(replace);
    int delta = replaceLen - searchLen;
    char *find = input;

    while (find = strstr(find, search)) {

        if (delta > 0) {
            realloc(input, strlen(input) + delta);
            find = strstr(input, search);            
        }

        memmove(find + replaceLen, find + searchLen, strlen(input) - (find - input));
        memmove(find, replace, replaceLen);
    }
}

该项目工程,直到我尝试 realloc() 在一个实例,其中被替换的串将超过最初的串。(它仍然的,这只是吐出错误以及结果)。

如果有帮助,调用代码看起来像:

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

void strrep(char *input, char *search, char *replace);

int main(void) {
    char *input = malloc(81);

    while ((fgets(input, 81, stdin)) != NULL) {
        strrep(input, "Noel", "Christmas");
    }
}
有帮助吗?

解决方案

作为一般规则,应 从来没有 做一个免费或分配一个用户提供的缓冲区。你不知道那里的用户分配的空间(在你的模块,在另一个DLL)所以你不能使用的任何分配功能的用户的缓冲区。

前提是你现在不做任何重新分配在你的功能,你应该改变它的行为一点点,就像在做的只有一个替换的,这样用户就能够计算所得的最大串的长度和提供一个缓冲足够长的时间为这一替代发生。

然后您可以创建的另一个功能做多的替代品,但是你将要分配的整个空间导致串和复制用户输入串。然后你必须提供一种方式来删除的字符串中的分配。

导致:

void  strrep(char *input, char *search, char *replace);
char* strrepm(char *input, char *search, char *replace);
void  strrepmfree(char *input);

其他提示

首先,对不起,我迟到了来的缔约方。这是我的第一个计算器的答案。:)

正如已经指出的,当realloc()是所谓的,你可能会改变指的记忆正在重新分配。当发生这种情况,这个论点"string"变为无效。即使你重新分配,改变超出范围一旦功能结束。

回答对《任择议定书》第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(-1);
}

作为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()新的缓冲器,返回,并让我们的呼叫者决定是否免费旧的文本。这有好处让的呼叫者保留原来的字符串!

只有在黑暗中拍摄的,因为我还没有尝试,但是当你重新分配返回的指针很像malloc.因为重新分配可以移动指如果需要的话,你是最有可能上操作无效的指如果你不做如下:

input = realloc(input, strlen(input) + delta);

其他人道歉迟到了派对-两个半月前。哦,好吧,我花费相当多的时间做的软件考古学。

我感兴趣的是,没有一个发表了评论意见明确地上的存储器泄漏的原始设计的,或关的一个错误。这是在观察记忆泄漏,告诉我到底为什么你得到的双免费的错误(因为,要精确,你被释放的同样的记忆中多次-和你们这样做之后,践踏了该已经释放了存储器)。

之前进行的分析,我同意一些人的说,你的接口比星;但是,如果处理存储器的泄漏/践踏问题并记录了'必须分配的存储要求,也可能是'好'。

有什么问题?好,你传递一个缓冲区realloc(),和realloc()返回你一个新的指针指向地区应该使用-和你忽视返回的价值。因此,realloc()有可能释放的原始存储器,然后你把它同针再次,它抱怨说,你在释放的同存的两倍,因为你通过的原始价值。这不仅泄漏的记忆,而是意味着你是继续使用原来的空间--和约翰*唐尼的照片在黑暗中指出,你是滥用realloc(),但不强调如何严重,你都这样做。还有一个关的一个错误因为你没有分配足够的空间NUL'\0'终止串。

存储器泄漏的发生是因为你不能提供一种机制来告诉呼叫者的最后价值。因为你不停地践踏原串加上空之后,它看起来像码的工作,但如果您的电话代码释放的空间,它也将获得双重免错误,或它可能会得到一个核倾倒的或相当于因为存储器控制信息是完全混乱。

你的代码也不保护对无限期的增长--考虑更换'诺埃尔*'与'Joyeux诺埃尔*'.每一次,你将增加7个字符,但是你会找到另一个诺埃尔*在替换为文本,并且扩大它,等等。我的修正(见下文)并没有解决这一问题的简单的解决方案可能是检查是否检索字符串中出现的替代串;一种替代方案是跳过取代串并继续搜索之后。第二具有某些非平凡的编码问题的解决。

因此,我的建议修订的你所谓的功能是:

char *strrep(char *input, char *search, char *replace) {
    int searchLen = strlen(search);
    int replaceLen = strlen(replace);
    int delta = replaceLen - searchLen;
    char *find = input;

    while ((find = strstr(find, search)) != 0) {
        if (delta > 0) {
            input = realloc(input, strlen(input) + delta + 1);
            find = strstr(input, search);            
        }

        memmove(find + replaceLen, find + searchLen, strlen(input) + 1 - (find - input));
        memmove(find, replace, replaceLen);
    }

    return(input);
}

这种代码不存检测分配的误差和可能的崩溃(但是,如果没有,漏水存储器),如果realloc()失败。看到史蒂夫*马奎尔的'书写的固体码'书的广泛讨论的存管理问题。

请注意,试图编辑你的代码摆脱html逃码。

好吧,虽然已有一段时间,因为我使用了C/C++、重新分配增长只会重复使用的存储器的指针的价值,如果有房在内存后你原来的块。

例如,认为这是:

(给别人..........)

如果你的指针指向的第x和。意味着免费存储位置,而你成长的存储器的尺寸指出,通过您的变量,由5个字节,它将取得成功。当然,这是一个简化例如块圆达到一定规模的为准,但无论如何。

然而,如果随后尝试增长,它通过了另外10个字节,只有5个可用的,它将需要移动的框在存储和更新你的指针。

然而,在如你传递的函数的一个指字,不是指你的变量,并因此而strrep功能在内部可能能够调整变量使用,它是一个局部的变量的strrep功能和您的电话代码将留下,与原来的指针可变的价值。

这一指针的价值,但是,已经释放。

在你的情况,输入是罪魁祸首。

然而,我会让另一个建议。在你的情况下,它看起来像 输入 变量确实输入,和如果是,它不应该被修改,在所有。

我因此,试图找到另一种方法做你想要做什么,而不改变 输入, 如副作用,这样可能很难追查。

这似乎是工作;

char *strrep(char *string, const char *search, const char *replace) {
    char *p = strstr(string, search);

    if (p) {
        int occurrence = p - string;
        int stringlength = strlen(string);
        int searchlength = strlen(search);
        int replacelength = strlen(replace);

        if (replacelength > searchlength) {
            string = (char *) realloc(string, strlen(string) 
                + replacelength - searchlength + 1);
        }

        if (replacelength != searchlength) {
            memmove(string + occurrence + replacelength, 
                        string + occurrence + searchlength, 
                        stringlength - occurrence - searchlength + 1);
        }

        strncpy(string + occurrence, replace, replacelength);
    }

    return string;
}

叹息,反正是有为后代码没有它吮吸?

重新分配是奇怪复杂的,应只用于在处理大量的存储大量的时间。即-在哪里,它实际上使你的代码的更快。

我已经看到代码在哪里

realloc(bytes, smallerSize);

使用,并努力调整大小的缓冲,使它更小。工作约一百万次,然后由于某些原因重新分配决定,甚至如果你是缩短了的缓冲器,它将给你一个漂亮的新副本。所以你崩溃,在随机地位1/2的后的第二糟的东西发生了。

总是使用的回报价值的分配.

我快的提示。

代替:
void strrep(char *input, char *search, char *replace)
尝试:
void strrep(char *&input, char *search, char *replace)

和比在身体:
input = realloc(input, strlen(input) + delta);

一般阅读有关传递的函数值为参考和realloc()description:).

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top