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

  1. when use

    strcpy(double_data + len, data); 

    you copy 1 byte double_data, nul terminator didn't allocate space for, should allocate space this

    char *double_data = malloc(2 * len + 1)); 
  2. the same applies allocation in for loop, namely

    all_rotations[i] = (char*)malloc(sizeof(char)* len); 

    and of course fix be

    all_rotations[i] = malloc(1 + len); 
  3. you never check if malloc() returns null, bad practice.

  4. not cast return value of malloc()

  5. do not use strlen() condition of loop unless length of string changes inside loop, because strlen() computes length of string on each call, making o(n) algorithm o(n2).

  6. 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

Popular posts from this blog

angularjs - ADAL JS Angular- WebAPI add a new role claim to the token -

php - CakePHP HttpSockets send array of paramms -

node.js - Using Node without global install -