Ваша функция split_str()
возвращает указатели в writablestring
, который является массивом arr
в node_create()
. Затем вы копируете эти указатели в node->tuple->fields[i]
- но массив arr
не будет существовать после выхода из функции node_create()
, поэтому эти указатели больше не будут действительными. Вместо этого вам нужно скопировать возвращенную строку в выделенную вами память (это также показывает, как вы можете использовать цикл for()
вместо вашего while()
, и вам также нужно освободить память, которая была выделена в split_str()
):
for (i = 0; array[i]; i++) {
node->tuple->fields[i] = malloc(strlen(array[i]) + 1);
if (!node->tuple->fields[i]){
printf("Erro ao alocar memoria em node_create() para node->tuple->fields[i]\n");
return NULL;
}
strcpy(node->tuple->fields[i], array[i]);
}
free(array);
Кроме того, ваш код предполагает, что массив, возвращаемый split_str()
, будет завершен NULL
, но функция не гарантирует этого. У этой функции есть множество других проблем (неправильный размер передан malloc()
, утечка памяти вызвана ненужными malloc()
) - поэтому вам также нужно это исправить:
char **split_str(char writablestring[], const char *sep)
{
char **array = malloc(strlen(writablestring) * sizeof array[0]);
if(!array) {
printf("Erro ao alocar memoria para o array em split\n");
return NULL;
}
char *token = strtok(writablestring, sep);
int i;
for (i = 0; (array[i] = token) != NULL; i++) {
token = strtok(NULL, " ");
}
return array;
}
(Обратите внимание, что array
не нужно передавать в качестве параметра - он все равно немедленно перезаписывается, поэтому я превратил его в локальную переменную).
Как только вы это сделаете, вы можете заметить, что на самом деле нет причин выделять array
в split_str()
, только копировать его содержимое в node->tuple->fields
и затем освобождать его. Вы также можете передать массив node->tuple->fields
в split_str()
и записать его прямо в него. Затем он может вернуть количество выделенных строк - это будет выглядеть так:
int split_str(char [], char **, const char *);
struct node_t *node_create(void *node_data)
{
struct node_t *node = NULL;
char *s = node_data;
size_t slen = strlen(s);
node = malloc(sizeof *node);
if (!node) {
printf("Erro ao criar um node!\n");
return NULL;
}
node->tuple = malloc(sizeof *node->tuple);
if (!node->tuple) {
printf("Erro ao criar o node->tuple\n");
free(node);
return NULL;
}
node->tuple->fields = malloc(slen * sizeof node->tuple->fields[0]);
if (!node->tuple->fields) {
printf("Erro ao criar o node->tuple->node_fields\n");
free(node->tuple);
free(node);
return NULL;
}
char arr[slen + 1];
strcpy(arr, s);
int i = split_str(arr, node->tuple->fields, " ");
node->tuple->n_fields = i;
node->tuple->timestamp = 0L;
node->next = NULL;
return node;
}
int split_str(char writablestring[], char **array, const char *sep)
{
char *token = strtok(writablestring, sep);
int i;
for (i = 0; token != NULL; i++) {
array[i] = malloc(strlen(token) + 1);
if (!array[i]) {
printf("Erro ao criar o array[i]\n");
break;
}
strcpy(array[i], token);
token = strtok(NULL, " ");
}
return i;
}