It appears that when the realloc function is called with a pointer to non-heap memory, the program dies with
Error(s):
Invalid memory reference (SIGSEGV)
Is it possible for my str_cat
function to detect this case and thus avoid calling realloc
Here is a sample program which demonstrates the problem:
//gcc 5.4.0
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
int str_cat(char *dest, size_t *dest_size, char *src);
int str_cat(char *dest, size_t *dest_size, char *src) {
// if there is sufficient free space in the dest buffer, append src,
// otherwise keep doubling the allocated size of dest until it is large
// enough to append src
size_t src_len = strlen(src);
size_t dest_len = strlen(dest);
if (src_len < *dest_size - dest_len) {
memcpy(dest+dest_len, src, src_len+1);
return 0;
} else {
char *new_dest = NULL;
size_t new_size = *dest_size * 2;
while (src_len >= new_size - dest_len) {
new_size *= 2;
}
if ((new_dest = realloc(dest, new_size)) != NULL) {
dest = new_dest;
*dest_size = new_size;
memcpy(dest+dest_len, src, src_len+1);
return 0;
} else {
return -1;
}
}
}
int main(void)
{
size_t heap_buf_size=5;
char *heap_buf = malloc(heap_buf_size);
size_t stack_buf_size=5;
char stack_buf[stack_buf_size];
*heap_buf = '\0';
if (str_cat(heap_buf, &heap_buf_size, "foo")) return -1;
printf("1. heap_buf %s\n", heap_buf);
printf("1. heap_buf_size %zu\n", heap_buf_size);
if (str_cat(heap_buf, &heap_buf_size, "bar")) return -1;
printf("2. heap_buf %s\n", heap_buf);
printf("2. heap_buf_size %zu\n", heap_buf_size);
stack_buf[0] = '\0';
if (str_cat(stack_buf, &stack_buf_size, "foo")) return -1;
printf("3. stack_buf %s\n", stack_buf);
printf("3. stack_buf_size %zu\n", stack_buf_size);
/* If the line below is uncommented, the program dies
with Invalid memory reference (SIGSEGV) */
// if (str_cat(stack_buf, &stack_buf_size, "bar")) return -1;
printf("4. stack_buf %s\n", stack_buf);
printf("4. stack_buf_size %zu\n", stack_buf_size);
return 0;
}