2013-06-28 12 views
5

私は動作しないmallocの不安定なバージョンを持っているGBDKを使ってGameboy ROMを書いています。私はまた、構造体の中で構造体を返すこともできません。それは私にポインタを返そうとしているので、structポインタを返すときにmallocを使わないようにする方法があるのだろうかと思っています。ただmallocを使わずに構造体へのポインタを返すことはできますか?

struct point { 
    char member_x; 
    char member_y; 
}; 


struct point *makepoint(char member_x, char member_y) { 
    struct point *temp = malloc(sizeof(struct point)); 

    temp->member_x = member_x; 
    temp->member_y = member_y; 

    return temp; 
}; 
+0

あなたの質問は、ポインタを返す方法ではなく、オブジェクトを作成する方法です。 – immibis

答えて

4

あり(構造体、または任意の型のオブジェクトへの)ポインタを返すために、様々な有効な方法がありますが、唯一の方法はへのポインタを返すように関数の前に存在しなかった新しいオブジェクトmalloc,realloc,calloc,aligned_alloc(C11)、または実装定義の割り当て関数(POSIXシステムではmmapなど)を使用することです。あなたが有効なポインタを返すことができ

他の方法は次のとおりです。

  1. static記憶域期間を持つオブジェクトへのポインタ。このようなオブジェクトのインスタンスが1回だけ存在するので、これは通常悪い方法です。

  2. 結果を格納する場所として使用するための引数として関数に渡されたポインタ。これは、呼び出し元にストレージを取得する責任を渡すので、しばしば良いアプローチになります。

  3. 何らかのグローバルプールから取得されたオブジェクトへのポインタ。これは、ローエンドのゲーム機器用の組込みシステムおよびゲーム設計において、非常に良いアプローチとなり得る。

+0

私はいくつかの答えを試しましたが、どれもG​​BDKで動作しないようです。私は、グローバルプールに関する3番目の提案に興味があります。あなたが私に指摘できるリソースがありますか? – MariusGames

+0

あなたがそれらを試して、彼らは "働いていない"と思う、私はあなたが何か別のものを試す必要があるとは思わない。これはおそらく、あなたがCで少しずつ読むべきであり、あなたが間違っていることを学ぶ(またはいくつかの特定の質問をする)ことを意味するでしょう。あなたのコードがあなたが望むことをしていないときはいつも、全く新しいアプローチを試みることは、効率的または信頼できるコード作成方法ではありません。 –

+0

ありがとう、私は知っています。読書の提案は大歓迎です:)私はまだ学んでいますが、GBDKが古いバージョンのCを使っているので構造体を返すことはできません。また、mallocが正しく動作していないという既知の問題です。私はすべての答えをもう一度見て行きます。 – MariusGames

0

create_struct(struct_name, char member_x, char member_y); 

これは私がmallocを使用して書かれているコードは次のとおりです。

私は基本的にやろうとしていることは、私はこのような何かを書くことができるようにしたいということです

構造体は別の場所に配置する必要があります(おそらくスタック上にbエストベット)。

0

あなたは、パラメータとして構造体を渡すと、関数は、それを初期化するかもしれない:

struct point *makepoint(struct point *pt, char x, char y) { 
    pt->x = x; 
    pt->y = y; 
    return pt; 
} 

をし、このようにそれを呼び出す:

struct point pt; 
makepoint(&pt, 'a', 'b'); 

をしかし、あなたは同様にちょうど行っているかもしれません。

struct point pt = { 'a', 'b' }; 
0

注意(struct pointのみ2つのバイトを占有)、この場合にあなたができること

#include <stdio.h> 

struct point { 
    char member_x; 
    char member_y; 
}; 

struct point makepoint(char member_x, char member_y) 
{ 
    struct point temp; 

    temp.member_x = member_x; 
    temp.member_y = member_y; 
    return temp; 
} 

int main(void) 
{ 
    struct point t = makepoint('a', 'b'); 

    printf("%c %c\n", t.member_x, t.member_y); 
    return 0; 
} 
2

それはmalloc関数を使用せずに、構造体へのポインタを返すことが可能です(これは大規模な構造体で行われるべきではありません)、代わりにstruct point *struct pointを返しますか?

I. 技術的には、はい。

struct foo *bar() 
{ 
    static struct foo f = { 1, 2, 3 }; 
    return &f; 
} 

しかし、私はあなたが実際にこのを(これは面白い副作用を持っているので、staticキーワードの意味をよく読んで)やりたい疑問:それが呼び出す関数を存続するようあなたは、構造体static作ることができます。いくつかの可能性があります:

II。 Cの標準ライブラリが取るアプローチは、呼び出し元に構造体の提供とメモリの管理を暗黙的に任せさせることです。代わりにポインタを返すので、機能は、構造体へのポインタを受け入れ、それを埋める:

void dostuff(struct foo *f) 
{ 
    foo->quirk = 42; 
} 

III。または(それも移動し、最適化することができます)それをしない、構造体自体は、それは悪くはない戻る:

struct foo bar() 
{ 
    struct foo f = { 1, 2, 3 }; 
    return f; 
} 

だから、あなたの毒を選択してください。

0

malloc()を修正できない場合は、事前に割り当てられたポイントを管理し、作成できるポイントの数を制限することができます。あなたはあなたのポイント容易な管理を可能にするために少し変更する必要があります:

union free_point { 
    union free_point *next; 
    struct point data; 
}; 

union free_point free_point_pool[MAX_POINTS]; 
union free_point *free_point_list; 

struct point *makepoint(char member_x, char member_y) { 
    static int i; 
    union free_point *temp; 

    temp = 0; 
    if (i == MAX_POINTS) { 
     if (free_point_list) { 
      temp = free_point_list; 
      free_point_list = temp->next; 
     } 
    } else { 
     temp = free_point_pool + i++; 
    } 

    if (temp) { 
     temp->data.x = x; 
     temp->data.y = y; 
    } 

    return &temp->data; 
}; 

その後、代わりにmakepoint()によって返される結果にfree()を呼び出す、あなたはfree_point_listの上に置くために新しい関数を作成する必要があります。

void unmakepoint (struct point *p) { 
    union free_point *fp = (union free_point *)p; 
    if (fp) { 
     fp->next = free_point_list; 
     free_point_list = fp; 
    } 
} 
0

最も簡単な方法は、ゼロオーバーヘッドがあるように、名前の初期化子を使用して作成された構造体を返すと、インライン関数でそうするだけです:

static inline struct point makepoint(char x, char y) { 
    return (struct point) { .x = x, .y = y }; 
} 

次にあなたが呼び出すことができますそれは次のようなものです:

struct point foo = makepoint(10, 20); 

もっと簡単ではありません!

関連する問題