2017-01-23 1 views
1

特定の条件を渡すすべての構造体を配列に集めるCプログラムを作成しようとしています。関数によって変更された後にC配列が壊れてしまう

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

struct Book { 
    char title[20]; 
    unsigned int published; 
    char authors[50]; 
    unsigned int pages; 
}; 

unsigned int get_books_from(unsigned int year, int length, struct Book data[], struct Book results[]); 

int main(int argc, char* argv[]) { 
    struct Book data[5]; 

    // Init book pool inside data 

    struct Book books[0]; 
    unsigned int books_count = get_books_from(1973, 5, data, books); 

    return 0; 
} 

unsigned int get_books_from(unsigned int year, int length, struct Book data[], struct Book results[]) { 
    results = (struct Book*) malloc(sizeof(struct Book)); 
    unsigned int results_count = 0; 

    int i; 
    for (i = 0; i < length; i++) { 
    if (data[i].published == year) { 
     *(results + results_count) = data[i]; 

     results = (struct Book*) realloc(results, (++results_count + 1) * sizeof(struct Book)); 
    } 
    } 

    return results_count; 
} 

ロジックは、しかし、(それがresultsと呼ばれています)get_books_from関数の外books配列の内容にアクセスしようと、すべてのデータが破損したときに、正常に動作しているようです。元のデータの一部はまだそこにありますが、正しい場所にはありません。データがシフトしたように見えます。私はbooksresultsの両方のポインタをチェックしていて、関数の終了後にそれらの変数がメモリ内の同じ場所を指していないように見えます。何が問題なの?あなたのget_books_from

+0

'構造体帳のブックは何ですか:

おそらく、この(未テスト、非エラーは簡潔にするためommitedコード、宣言との#includeをチェックする)のような何かをしたいです[0]; 'そんなことはあまり意味がありません。 –

答えて

5

はここresultsの値が変更されます。

results = (struct Book*) realloc(results, (++results_count + 1) * sizeof(struct Book)); 

をしかし、それは、呼び出し側がresultsの新しい値を取得するための方法を提供していません。

さらに悪いことに、mainにスタックに割り当てられたdataget_books_fromを呼び出します。あなたはreallocできません。 reallocのドキュメントによれば、再割り当てしようとしているポインタは、前回のmalloccalloc、またはreallocの呼び出しによって返されたはずです。幸いにも、あなたはその値を無視します。しかし、のstruct Book data[5];は理解できません。なぜスタックにスペースを割り当てるのですか?

+0

ああ私。あなたが正しい。私は関数のポインタを値渡し、realloc()で変更しません。 –

+0

また、動的に割り当てないため、動的に再割り当てすることはできません。 –

+0

私はしませんでしたか?それは 'get_books_from'の最初の行に' malloc'されています。 –

0

他の回答に加えて:

unsigned int get_books_from(unsigned int year, int length, struct Book data[], struct Book **results); 

int main(int argc, char* argv[]) { 
    struct Book data[5]; 

    // Init book pool inside data 

    struct Book *books; 
    unsigned int books_count = get_books_from(1973, 5, data, &books); 

    return 0; 
} 

unsigned int get_books_from(unsigned int year, int length, struct Book data[], struct Book **results) { 
    *results = (struct Book*) malloc(sizeof(struct Book)); 
    unsigned int results_count = 0; 

    int i; 
    for (i = 0; i < length; i++) { 
    if (data[i].published == year) { 
     *(*results + results_count) = data[i]; 

     *results = (struct Book*) realloc(*results, (++results_count + 1) * sizeof(struct Book)); 
    } 
    } 

    return results_count; 
} 
+0

'realloc'に渡すときに' results'を一度参照解除するのを忘れました。それ以外は、うまく動作します。 :) –

+0

@キューブ。そうです、私は修正しました。書かれているとおり:これはテストされていないコードです;-)。しかし、明らかにあなたはその考えを持っています。 –

関連する問題