Matthew Schinckel Matthew Schinckel - 16 days ago 8
C Question

Why am I getting a malloc: double free error with realloc()?

I've tried to write a string replace function in C, which works on a

char *
, which has been allocated using
malloc()
. It's a little different in that it will find and replace strings, rather than characters in the starting string.

It's trivial to do if the search and replace strings are the same length (or the replace string is shorter than the search string), since I have enough space allocated. If I try to use
realloc()
, I get an error that tells me I am doing a double free - which I don't see how I am, since I am only using
realloc()
.

Perhaps a little code will help:

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);
}
}


The program works, until I try to
realloc()
in an instance where the replaced string will be longer than the initial string. (It still kind of works, it just spits out errors as well as the result).

If it helps, the calling code looks like:

#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");
}
}

Answer

As a general rule, you should never do a free or realloc on a user provided buffer. You don't know where the user allocated the space (in your module, in another DLL) so you cannot use any of the allocation functions on a user buffer.

Provided that you now cannot do any reallocation within your function, you should change its behavior a little, like doing only one replacement, so the user will be able to compute the resulting string max length and provide you with a buffer long enough for this one replacement to occur.

Then you could create another function to do the multiple replacements, but you will have to allocate the whole space for the resulting string and copy the user input string. Then you must provide a way to delete the string you allocated.

Resulting in:

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