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");
}
}
The error of double free or corruption in C++ means that our program somehow invokes the free() C++ object with an illegal pointer variable. When we use smart pointers such as shared_ptr, we must check because if we call the function get(), we are directly using the raw pointer.
Double Free A simple technique to avoid this type of vulnerability is to always assign NULL to a pointer after it has been freed. Subsequent attempts to free a null pointer will be ignored by most heap managers.
A double free in C, technically speaking, leads to undefined behavior. This means that the program can behave completely arbitrarily and all bets are off about what happens.
If realloc fails, it returns null pointer, but it doesn't deallocate the old memory.
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);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With