So I have a couple of functions that work with a string
type I have created. One of them creates a dynamically allocated sting. The other one takes said string, and extends it. And the last one frees the string. Note: The function names are changed, but all are custom-defined by me.
string new = make("Hello, ");
adds(new, "everyone");
free(new);
The code above works - it compiles and runs fine. The code below does not work - it compiles, runs, and then
string new = make("Hello, ");
adds(new, "everyone!");
free(new);
The difference between the code is that the adds()
function is adding 1 more character (a !
). The character it adds makes no difference - just the length. Just for completeness, the following code does not work:
string new = make("Hello, ");
adds(new, "everyone");
adds(new, "!");
free(new);
Oddly, the following code, which uses a different function, addc()
(which adds 1 character instead of a string) works:
string new = make("Hello, ");
adds(new, "everyone");
addc(new, '!');
free(new);
The following, which also does the same thing, works:
string new = make("Hello, everyone!");
free(new);
The error that all the ones that don't work give is this:
test(526) malloc: *** error for object 0x100130: double free
*** set a breakpoint in malloc_error_break to debug
(test
is the extremely descriptive name of the program I have this in.)
As far as the function internals, my make()
is a call to strlen()
and two calls to malloc()
and a call to memcpy()
, my adds()
is a call to strlen()
, a call to realloc()
, and a call to memcpy()
, and my free()
is two calls to the standard library free()
.
So are there any ideas why I'm getting this, or do I need to break down and use a debugger? I'm only getting it with adds()
es of over a certain length, and not with addc()
s.
Breaking down and posting code for the functions:
typedef struct _str {
int _len;
char *_str;
} *string;
string make(char *c)
{
string s = malloc(sizeof(string));
if(s == NULL) return NULL;
s->_len = strlen(c);
s->_str = malloc(s->_len + 1);
if(s->_str == NULL)
{
free(s);
return NULL;
}
memcpy(s->_str, c, s->_len);
return s;
}
int adds(string s, char *c)
{
int l = strlen(c);
char *tmp;
if(l <= 0) return -1;
tmp = realloc(s->_str, s->_len + l + 1);
if(!tmp) return 0;
memcpy(s->_str + s->_len, c, l);
s->_len += l;
s->_str[s->_len] = 0;
return s->_len;
}
void myfree(string s)
{
if(s->_str) free(s->_str);
free(s);
s = NULL;
return;
}