#include <stdlib.h>
#include <stdio.h>
#include <string.h>

// Функция принимает себе указатель на строку, разделитель и возвращает массив строк
// string - строка которую нужно разделить
// delimiter - разделитель
// countString - возвращает колличество строк в массиве
char** split(char * string, const char * delimiter, int * countString)
{
    char *token, *last;
    char ** arrayString;    // Массив строк, возвращаемый в конце функции
    char * str;             // переменная нужна для создания копии строки для разделения в куче
    int count;              // Текущее количества строк в массиве 
    int count_malloc;       // Это для примера, задает размер arrayString ( в будущем будет по другому )

    count = 0;
    count_malloc = 10;
    arrayString = (char**)malloc(count_malloc * sizeof(char*)); // выделяем память для массива строк
    str = (char*)malloc(strlen(string)+1);      // Выделяем память для копии строки
    strcpy(str,string);                         // создаем копию строки в куче

    // Начинается разделение
    token = strtok_r(str, delimiter, &last);
    while (token != NULL) {
        arrayString[count] = (char*) malloc(strlen(token)+1); // Выделяется память для текущего токена
        strcpy( arrayString[count] ,token);                   // копируем токкен в массив
        token = strtok_r(NULL, delimiter, &last);
        count++;
    }

    free(str); //   !!! Выдает ошибку double free or corruption

    *countString = count;
    return arrayString;
}

int main(int count, char ** arg) {
    int countString;
    char ** arrayString;

    arrayString = split("param1 param2 param3 param4 param5 param6", " ",&countString);

    for(int i = 0; i < countString; i++) {
        printf ("%i: %s\n",i, arrayString[i]);
    }

    // free отрабатывает нормально
    for(int i = 0; i < countString; i++) {
        free(arrayString[i]);
    }

    // !!! Ошибка free(): invalid next size (fast)
    free(arrayString);
    return 0;
}