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,nulterminator didn't allocate space for, should allocate space thischar *double_data = malloc(2 * len + 1));the same applies allocation in
forloop, 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