2016-04-28 8 views
-2

リンクリストからメッセージを取得し、そのメッセージをリストから削除すると、セグメンテーションフォールトが発生します。セグメンテーションフォルトのリンクリスト結果を取得および削除する

最初のメッセージとサーバーメッセージ構造体:

// used to store messages. 
struct server_message { 
    char message[80]; 
    char id[80]; 
    struct server_message *next_msg; 
}; 

//head of the list 
static struct server_message *first_message = NULL; 

のGetメッセージ機能

char *get_message(char *id) { 
    char *message; 
    char *not_found =(char *) malloc(sizeof(char) * 20); 
    not_found = "No messages available"; 
    struct server_message *curr_msg = first_message; 
    struct server_message *prev_msg = first_message; 

    if (curr_msg != NULL && (strcmp(curr_msg->id, id) != 0)) { 
     strcpy (message, curr_msg->message); 
     //Remove message 
     first_message = NULL; 
     return message; 
    } 


    while (curr_msg->next_msg != NULL) { 
     curr_msg = curr_msg->next_msg; 

     if (strcmp(curr_msg->id, id) != 0) { 
      strcpy (message, curr_msg->message); 
      //Remove message 
      prev_msg->next_msg = curr_msg->next_msg; 
      return message; 
     } else { 
      prev_msg = curr_msg; 
     } 
    } 
    return not_found; 
} 

それでもフォルトSEGコードを更新しました

char *get_message(char *id) { 
    char *message = (char *) malloc(sizeof(char) * 80); 
    char *not_found=(char *) malloc(sizeof(char) * 20); 
    strcpy(not_found, "No messages available"); 
    struct server_message *curr_msg = first_message; 
    struct server_message *prev_msg = NULL; 

    while (curr_msg->next_msg != NULL) { 

     if (strcmp(curr_msg->id, id) != 0) { 
      strcpy (message, curr_msg->message); 
      //Remove message 
      if (prev_msg == NULL) { 
       first_message = curr_msg->next_msg; 
      } else { 
       prev_msg->next_msg = curr_msg->next_msg; 
      } 
      return message; 
     } else { 
      prev_msg = curr_msg; 
      curr_msg = curr_msg->next_msg; 
     } 
    } 
    return not_found; 
} 
+0

デバッガ....................... –

+1

このコードは大きく壊れています。メモリリーク、初期化されていないポインタの逆参照など。ちょうどカップル:(1) 'message'は決して初期化されませんが、あなたはそれを格納しようとします。セグメンテーションフォルト。 (2) 'not_found'は' malloc'からの格納に設定されます。しかし、その記憶領域が使用される前に、 'not_found'はすぐに定数文字列に設定されます。メモリーリーク。それ以上のものがあると確信しています。これはバグを見つけるよりもCを知らないという問題のほうが多いようです。 –

+0

@TomKarzesメッセージの場合、 'char message [80]'を使用できますか? –

答えて

0

改訂完全な例:

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

// used to store messages. 
struct server_message { 
    char message[80]; 
    char id[80]; 
    struct server_message *next_msg; 
}; 

//head of the list 
static struct server_message *first_message = NULL; 

char *get_message(char *id) { 
    struct server_message *curr_msg = first_message; 
    struct server_message *prev_msg = NULL; 

    while (curr_msg != NULL) {    /* FIX1: iterate until we do not have an item */ 
     if (strcmp(curr_msg->id, id) == 0) { /* FIX2: 0 is equal */ 
      //Remove message 
      if (prev_msg == NULL) { 
       first_message = curr_msg->next_msg; 
      } else { 
       prev_msg->next_msg = curr_msg->next_msg; 
      } 
      return strdup(curr_msg->message); 
     } else { 
      prev_msg = curr_msg; 
      curr_msg = curr_msg->next_msg; 
     } 
    } 
    return strdup ("No messages available"); 
} 

struct server_message d = {"foo-4", "4", 0}; 
struct server_message c = {"foo-3", "3", &d}; 
struct server_message b = {"foo-2", "2", &c}; 
struct server_message a = {"foo-1", "1", &b}; 

int main(int argc, char *argv[]) 
{ 
     char *t; 

     first_message = &a; 

     t = get_message("1"); 
     printf ("1: %s\n", t); 
     free (t); 

     t = get_message("3"); 
     printf ("3: %s\n", t); 
     free (t); 

     t = get_message("10"); 
     printf ("10: %s\n", t); 
     free (t); 

     return 0; 
} 
+0

あなたが述べたようにコードを更新しようとしましたが、まだ失敗しています。私が投稿した更新を見てもらえますか? –

+0

'not_found'に20バイトを割り当てました。' 'No messages available ''は20バイトを超えています。また、 'first_message'ポインタにヌルチェックを追加してください。 – kuro

+0

私はまた、20バイトでは不十分であることを知りませんでした。not_foundリターンに関して最も簡単なのは、 'strdup(" No messages available ");' を返すのですが、コードにもメモリリークがあります。 –

関連する問題