我是c中的菜鸟,我有这个代码无法正常工作,因为我为char **指针做了一些糟糕的内存allcoation。能否请你帮忙?提前做了很多。 代码:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct node_t {
struct tuple_t *tuple; //Entrada na lista
struct node_t *next; //o node seguinte da lista
};
struct tuple_t {
long timestamp; /* instante de criacao do tuplo*/
int n_fields; /* numero de campos deste tuplo */
char **fields; /* array com campos do tuplo */
/* 4 + 4 + 4 bytes?? */
};
char ** split_str(char [], char **, const char *);
struct node_t *node_create(void *node_data){
struct node_t *node = NULL;
node = (struct node_t *)malloc(sizeof(struct node_t));
if(!node){
printf("Erro ao criar um node!\n");
return NULL;
}
node->tuple = (struct tuple_t *)malloc(sizeof(struct tuple_t));
if(!node->tuple){printf("Erro ao criar o node->tuple\n"); free(node); return NULL;}
node->tuple->fields = (char ** )malloc(strlen((char *) node_data) * sizeof(char *));
if(!node->tuple->fields){ printf("Erro ao criar o node->tuple->node_fields\n"); free(node->tuple); free(node); return NULL; }
char **array;
const char *sep=" ";
char *s = (char *)node_data;
char arr[strlen(s)];
int i = 0;
while(arr[i++]=s[i]);
array = split_str(arr,array, sep);
i = 0;
while(array[i]){
node->tuple->fields[i] = (char *)malloc((strlen(array[i])) * sizeof(char));
if(!node->tuple->fields[i]){
printf("Erro ao alocar memoria em node_create() para node->tuple->fields[i]\n");
return NULL;
}
node->tuple->fields[i] = array[i];
// printf("array[i]=%s\n",array[i]);
// printf("node->tuple->fields[i]=%s\n",node->tuple->fields[i]);
i++;
}
node->tuple->n_fields = i;
node->tuple->timestamp = 0L;
node->next = NULL;
return node;
}
char** split_str(char writablestring[],char **array, const char *sep ){
array = malloc(strlen(writablestring) + 1);
if(! array){printf("Erro ao alocar memoria para o array em split\n"); return NULL;}
char *token = strtok(writablestring, sep);
int i=0;
while(token != NULL)
{
array[i] = malloc(strlen(token)+1);
if(!array[i])
return NULL;
array[i] = token;
token = strtok(NULL, " ");
i++;
}
return array;
}
int main(int argc, char** argv)
{
void * n_data = "hello 123 ploc";
struct node_t * node = node_create(n_data);
printf("node->num_fields=%d\n", node->tuple->n_fields);
int i=0;
while( node->tuple->fields[i] ){
printf("node->tuple->fields[%d]=%s\n",i,node->tuple->fields[i]);
i++;
}
return 0;
}
结束代码。
答案 0 :(得分:1)
您的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;
}
答案 1 :(得分:0)
尝试这样的事情:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
struct tuple_t
{
long timestamp; /* instante de criacao do tuplo*/
int n_fields; /* numero de campos deste tuplo */
char** fields; /* array com campos do tuplo */
};
struct node_t
{
struct tuple_t* tuple; //Entrada na lista
struct node_t* next; //o node seguinte da lista
};
char** split_str(const char *, const char *, int *);
void node_destroy(struct node_t*);
struct node_t* node_create(char* node_data)
{
struct node_t* node = (struct node_t *) malloc(sizeof(struct node_t));
if(!node)
{
printf("Erro ao criar um node!\n");
return NULL;
}
node->tuple = (struct tuple_t *) malloc(sizeof(struct tuple_t));
if(!node->tuple)
{
printf("Erro ao criar o node->tuple\n");
node_destroy(node);
return NULL;
}
node->tuple->timestamp = 0L;
node->tuple->fields = split_str(node_data, " ", &(node->tuple->n_fields));
if(!node->tuple->fields)
{
printf("Erro ao criar o node->tuple->node_fields\n");
node_destroy(node);
return NULL;
}
node->next = NULL;
return node;
}
void node_destroy(struct node_t* node)
{
if(node)
{
if(node->tuple)
{
if(node->tuple->fields)
{
for(int i = 0; i < node->tuple->n_fields; ++i)
free(node->tuple->fields[i]);
free(node->tuple->fields);
}
free(node->tuple);
}
free(node);
}
}
char** split_str(const char* str, const char* sep, int* found)
{
if (found) *found = 0;
int len = strlen(str);
char** array = (char**) malloc(len * sizeof(char*));
if(!array)
{
printf("Erro ao alocar memoria para o array em split\n");
return NULL;
}
++len;
char* writablestring = (char*) malloc(len);
if(!array)
{
printf("Erro ao alocar memoria para writeablestring em split\n");
free(array);
return -1;
}
strncpy(writablestring, str, len);
char* token = strtok(writablestring, sep);
int i = 0;
while(token)
{
len = strlen(token) + 1;
array[i] = (char*) malloc(len);
if(!array[i])
{
printf("Erro ao alocar memoria para o array item em split\n");
free(writeablestring);
for(int j = 0; j < i; ++j)
free(array[j]);
free(array);
return NULL;
}
strncpy(array[i], token, len);
++i;
token = strtok(NULL, sep);
}
free(writeablestring);
if(found) *found = i;
return array;
}
int main(int argc, char** argv)
{
char* n_data = "hello 123 ploc";
struct node_t* node = node_create(n_data);
if(node)
{
printf("node->tuple->n_fields=%d\n", node->tuple->n_fields);
for(int i = 0; i < node->tuple->n_fields; ++i)
printf("node->tuple->fields[%d]=%s\n", i, node->tuple->fields[i]);
node_destroy(node);
}
return 0;
}