2010-11-25 11 views
1

私はcのnoobです。このコードは正しく動作しません。これは、char **ポインタに対していくつかの不良なメモリがあるためです。助けてもらえますか? Thxは事前にたくさんある。 コード:cポインターのメモリ割り当てへのポインタ

#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

を、私はいくつかの大ざっぱ物事を見るようになります - それは、割り当てられた文字列の数を返すことができます。例えば ​​'node_data'を' void * 'として渡し、' node-> tuple-> fields [i] 'にメモリを割り当ててすぐに上書きします(おそらく' memcpy'や 'strcpy'を意味します)。メモリリーク。しかし、あなたが全体としてやっていること、そして各部で何をしようとしているのかを説明することは役に立ちます。 –

+0

申し訳ありませんが、私は答える時間がありませんでした。基本的に、私は分割された文字列をtuple_t構造体の 'fields'フィールドに追加したかったのです。しかし、まあ、コードは乱雑です。幸いにも、今私は解決策を持っています;) – alinnemet

答えて

1

split_str()関数はwritablestringへのポインタを返します。arrnode_create()です。これらのポインタをnode->tuple->fields[i]にコピーしますが、の配列は関数node_create()の終了後に存在しないため、これらのポインタは無効になります。代わりにに返された文字列を割り当てたメモリにコピーする必要があります(これはwhile()の代わりにfor()ループを使用する方法を示しており、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がパラメータとして渡さする必要はないことに注意してください - それはすぐに上書きされるので、私はそれをローカル変数に変えました)。あなたはこれをやったら


、あなたは本当にのみnode->tuple->fieldsにその内容をコピーするには、split_str()arrayを割り当て、それを解放する理由がないことに気づくかもしれません。配列node->tuple->fieldssplit_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; 
} 
+0

thxたくさんのおい、これらのヒントは今事をより明確にします... – alinnemet

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; 
} 
+0

おい!それはたくさんの男...私のコードはこれに比べて本当にクラップスでした...素敵でスムーズです。 – alinnemet

関連する問題