ページ 11

動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月11日(土) 00:48
by T.K.
こんばんはT.K.といいます。
VC++を利用しています。

質問したい内容はタイトルのとおり、
動的にメモリ確保した構造体配列のポインタ渡し
のやり方です。

普通に考えると、
#include <stdlib.h>
#include <malloc.h>

struct Str
{
	int i;
};

void f(/*?????*/)
{
	a[1]->i = 1;
}

int main()
{
	Str* a;
	a = static_cast<Str*>(calloc(3, sizeof Str));
	a[1].i = 0;
	f(&a);

	return 0;
}
といった形になったのですが、これでは定義文の引数を
どのように宣言すべきかわかりません。

どのように書けばポインタを渡せるのでしょうか。
ご教授お願いします。

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月11日(土) 03:20
by 御津凪
関数 f の引数には Str* a と定義し、
f(a);
として呼び出します。

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月11日(土) 07:47
by toyo
void f( Str** a )

void f( Str* a[ ] )

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月11日(土) 14:40
by T.K.
返信ありがとうございます。

確かに自分も最初は
void f( Str** a )
でよいかなと思い、記述していたのですが、
これでは関数f内の代入でアクセス違反が起きます。
(最初に書いておくべきでした。すみません)

理由はおそらく、通常のダブルポインタと
メモリを動的に確保した配列のポインタは、形式こそ
似ていますが、指している場所が微妙にずれているからだと思います。

何か新しい型でも用意すれば解決するかなと思ったのですが、
C++でメモリの大きさを変えたまったく新しい型を用意する方法
を知らないために断念しました。

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月11日(土) 14:53
by たかぎ
もしかして、
void f(Str (*a)[3]);
を期待しているのでしょうか?
それであれば、呼び出し側は、
Str (*a)[3];
a = static_cast<Str(*)[3]>(calloc(3, sizeof Str));
とする必要があります。

ただ、こんなことをするより、素直に、
std::vector<Str> a(3, Str());
とした方がよいと思います。

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月11日(土) 17:42
by box
> これでは関数f内の代入でアクセス違反が起きます。

ポインターへのポインターを使うようにf()のコードを
書くこともできます。

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月12日(日) 15:07
by T.K.
返信ありがとうございます。
それから、こちらの返信が大変遅れました。ごめんなさい。

実現したかったことはvectorを使用することでとてもきれいに
解決できました。たかぎさんありがとうございました。

>>boxさん
ポインタのポインタを使う方法は、よくわかりませんでした。
もしよければ何かヒントをいただけますか?

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月12日(日) 15:50
by box
Cの例です。適当にアレンジしてください。

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

typedef struct {
	int i;
} Str;

void f(Str **a)
{
	a[0][1].i = -789;
	(*a)[2].i = 890;
}

int main(void)
{
	Str *a;
	
	a = (Str *) malloc(sizeof(Str) * 3);
	if (!a) exit(1);
	
	a[1].i = 123;
	a[2].i = 456;
	
	printf("【変更前】\n");
	printf("a[1].i=%d\n", a[1].i);
	printf("a[2].i=%d\n", a[2].i);
	
	f(&a);
	
	printf("【変更後】\n");
	printf("a[1].i=%d\n", a[1].i);
	printf("a[2].i=%d\n", a[2].i);
	
	free(a);
	return 0;
}

Re:動的にメモリ確保した構造体配列のポインタ渡し

Posted: 2008年10月18日(土) 03:18
by T.K.
>>boxさん

理解しました。
丁寧な返信ありがとうございました。