c - Heap corruption while freeing memory -
i'm struggling piece of code. name suggests, function should return array of strings represents rotations of string given parameter.
char **str_all_rotations(const char *data) { int = 0; /* loop counter */ len = strlen(data); /* len of input */ /******************/ /* malloc memory */ char **all_rotations = (char**)malloc(sizeof(char*)* len); char *double_data = (char*)malloc(len * 2 * sizeof(char)); (i = 0; < len; i++) { all_rotations[i] = (char*)malloc(sizeof(char)* len); } /*******************/ /* rotations part */ strcpy(double_data, data); strcpy(double_data + len, data); (i = 0; < len; i++) { strncpy(all_rotations[i], double_data + i, len); all_rotations[i][len] = '\0'; } free(double_data); /* release memory */ return all_rotations; }
it works fine algorithmic perspective, simple call of function
char *str = "omgillsetyouonfire"; char **asdf = str_all_rotations(str); (int = 0; < strlen(str); i++) { free(asdf[i]); } free(asdf);
fails, because of heap corruption. can't see whats wrong. how 1 debug kind of errors ?
there problems code
when use
strcpy(double_data + len, data);
you copy 1 byte
double_data
,nul
terminator didn't allocate space for, should allocate space thischar *double_data = malloc(2 * len + 1));
the same applies allocation in
for
loop, namelyall_rotations[i] = (char*)malloc(sizeof(char)* len);
and of course fix be
all_rotations[i] = malloc(1 + len);
you never check if
malloc()
returnsnull
, bad practice.do not use
strlen()
condition of loop unless length of string changes inside loop, becausestrlen()
computes length of string on each call, making o(n) algorithm o(n2).the standard requires
sizeof(char) == 1
, it's cluttering code.
this own code fixed address issues mentioned above
#include <stdio.h> #include <string.h> #include <stdlib.h> char ** str_all_rotations(const char *const data) { int index; char **all_rotations; char *double_data; int length; if (data == null) return null; length = strlen(data); index = 0; all_rotations = malloc(length * sizeof(*all_rotations)); if (all_rotations == null) return null; double_data = malloc(2 * length + 1); if (double_data == null) goto cleanup; (index = 0 ; index < length ; index++) { all_rotations[index] = malloc(1 + length); if (all_rotations[index] != null && index < 4) continue; goto cleanup; } memcpy(double_data, data, length); memcpy(double_data + length, data, length); double_data[2 * length] = '\0'; (index = 0 ; index < length ; index++) { memcpy(all_rotations[index], double_data + index, length); all_rotations[index][length] = '\0'; } free(double_data); return all_rotations; cleanup: while (index >= 0) free(all_rotations[index--]); free(all_rotations); free(double_data); return null; } int main(void) { char *str = "omgillsetyouonfire"; char **asdf = str_all_rotations(str); if (asdf != null) { (int = 0 ; str[i] != '\0' ; i++) { printf("%s\n", asdf[i]); free(asdf[i]); } free(asdf); } return 0; }
Comments
Post a Comment