12/12/09 09:16:37.01
_,rr-―''''¨゙゙゙ ̄ ̄ ̄ ̄ ̄`゙゙゙゙゙゙゙゙''ヘi、、 ,,,,-―---、
,r‐'″ ._,,,, `'lri,!'''″ ゙l
.,,,″ ,,r'"` ゙゙l, ゙ヘ, |
!アr, .l°.ェ'ニ,コ .| ゚ヘ、 |
`'i、 .く_,、vr''″ ., ゙'i、 .,,/
゙X、 ト ゙!,゛ .,,r‐--、
,、_,、 .,,,,r‐'″ | } .,,r‐'^’ .|゜
め゙゚“゙゙~゛ |  ̄` .,l゙
| ,i´ ,l゙
゙!、 ,i´ ,ノ
.'┐ ,,-° '=,, /`
.゚!, ,,,,r'″ ゙┐ ,l゙
゚'r, .''''"` │ .,,-''i、 /
`''x, .| | .,,r'" .゙┐ ,i´
~'ヘi,,, | |_,r・″ 'ヘ,、 l゙
`¬--|i,,,,,,,,,,,,,,,,v、r',广 ゙ヘ〟 ,l゙
`゙'ーぃ--r'″ `'―、,,,,/
3:デフォルトの名無しさん
12/12/09 10:12:17.78
動的二次元配列を作ろうとしているのですが
k=10
char** a=NULL;
a=(char**)malloc(sizeof(char*)*2);
a[1]=(char*)malloc(sizeof(char)*k);
こういう時に
a[1][100]とかに要素数入れられるのがわからんし
sizeof *a[1]がkをいくつにしても4になる理由がわかりません
助けてください
4:デフォルトの名無しさん
12/12/09 10:19:35.51
ポインタは配列じゃないから、サイズの管理なんてしてないし、
mallocは単にメモリを確保するだけで、確保外のメモリを読み書きするのを
禁止してくれたりはしないから、書きこんだらあらぬデータが壊れるかもだし、
エラーで落ちるかも。
5:デフォルトの名無しさん
12/12/09 10:20:43.28
>>1
おつ!
6:デフォルトの名無しさん
12/12/09 10:25:39.80
>>4
ありがとう
上の例でa[1][9]まできっちりメモリ確保されたか確認する手段ってあるんですか?
7:デフォルトの名無しさん
12/12/09 10:26:51.15
>>3
a=(char**)malloc(sizeof(char*)*2);
で、char *というポインタ値を入れる配列が2個できます。
a[0] と a[1]です。ポインタ値は(32bitでは)4bytesです。
a[1]=(char*)malloc(sizeof(char)*k);
で、charという値を入れる配列が k個できます。
a[1][0],a[1][1],,,,a[1][k-2],a[1][k-1]です。
charは、(Cの規格では)1bytesです。
> sizeof *a[1]がkをいくつにしても4になる理由がわかりません
多分 sizeof(a[1]) の事だと思いますが、a[1]は、上に書いたように
ポインタ値(4bytes)なので4になります。
ちなみに、k = 10 であれば、
> a[1][100]とかに要素数入れられるのがわからんし
これは確保した領域外へのアクセスなので、やってはいけません。
8:デフォルトの名無しさん
12/12/09 10:27:49.76
>>6
malloc() の戻り値が NULL 以外なら大丈夫。
ということになっている
9:デフォルトの名無しさん
12/12/09 10:31:07.09
理解できました
みなさん回答ありがとうございます。本当に勉強になりました。
本当に感謝しています
10:デフォルトの名無しさん
12/12/09 10:40:13.50
>>3
a[1][100]のように2次元インデックスでアクセスしたいならば↓のように書く。(C99)
可変長配列はC99の規格なのでそれ以前では定数で与えなければだめ。
a の宣言後にkの値を変更してもだめ。
char (*a)[k] = malloc(sizeof(a[0]) * 2);
11:デフォルトの名無しさん
12/12/09 10:55:23.43
>>10
えーと よく理解できないです
a[0]
a[1]
をそれぞれ別の要素数にしたいのでkを固定しちゃまずいのでは?
12:デフォルトの名無しさん
12/12/09 10:57:18.53
>a の宣言後にkの値を変更してもだめ。
他は兎も角、これについては何を言いたいのか判らん。
c99より前ならそもそもそんな宣言はできないから変更してもダメもへったくれもないわけで。
13:デフォルトの名無しさん
12/12/09 11:00:17.45
>>3
やろうとしていることは、可変長の二次元配列ではなくて
可変長の配列の可変長の配列だろ。
つまり、要素数が例えば2x100とかではなく100+50+30+200のような。
C++で言うところのstd::vector<std::vector<int> >でほぼできることだけど、Cだと
別途管理配列を要素する必要があるね。
14:デフォルトの名無しさん
12/12/09 11:05:48.28
>>11
頭おかしいなお前
>>10のkは>>3のkと同じアルファベットでも全然別物として使ってるんだよ
>>10のピントのずれたレスに惑わされるなんてやばいぞ?
15:デフォルトの名無しさん
12/12/09 11:10:48.42
まずジャグ配列と2次元配列の区別くらいしよう
簡単な用語の話なんだから
2次元配列:長方形
ジャグ配列:ギザギザ
16:デフォルトの名無しさん
12/12/09 11:26:44.16
>>12
お前バカだろ。kを変えるなと言っているのだからC99での宣言に決まってる。
17:デフォルトの名無しさん
12/12/09 11:29:44.13
sizeofを乱発しているソースを見ると、コンパイル時とランタイムの
区別がついてるか心配になる。
18:デフォルトの名無しさん
12/12/09 11:42:14.84
>>16
なるほど、その前の行でc99以外に言及しているからその続きかと思った。
まぁ、c99の話だとしても過去の宣言に遡って要素数が変わるなんて想像さえできなかったが。
19:デフォルトの名無しさん
12/12/09 12:05:50.34
実装を考えると宣言後にも(宣言時の)kの値を参照する必要がある。
kを直接参照するとワヤになるので、宣言時の値を退避しておくのだろう。
20:デフォルトの名無しさん
12/12/09 18:09:22.33
名前と属性を管理するデータベースを作りたいと思っててます。
例えば、
Aさんは「水泳」属性、「走行」属性を持ちます。
Bさんは「水泳」属性、「暗視」属性を持ちます。
この場合、
Name | Attribution
A | 水泳
A | 走行
B | 水泳
B | 暗視
のように登録するのは効率が悪いと思うのです。
何か効率のいいデータベースの構成はないでしょうか?
21:デフォルトの名無しさん
12/12/09 18:18:05.63
>>20
属性の種類に限りがあるかどうかで変わる
22:デフォルトの名無しさん
12/12/09 18:19:49.85
table1(table1ID,name)
table2(table2ID,Attribution )
table3(table1ID,table2ID)
テーブル名と主キー名は適当なんで
好きな名前におきかえてね
23:デフォルトの名無しさん
12/12/09 18:20:44.24
データベース板っていうのがあるんだけど・・・。
とりあえずこの情報だけじゃ判断しかねるわ
24:デフォルトの名無しさん
12/12/09 18:32:41.22
>>21
限りはあります
>>22
何のコードですか?
MySQLでしょうか?
>>23
何が足りないでしょうか。
25:デフォルトの名無しさん
12/12/09 18:43:34.70
>>24
データの種類の数
一人当たりの属性の数
26:デフォルトの名無しさん
12/12/09 18:45:21.06
たとえば、属性の数が数種類くらいなら、ビットを使って所属属性を設定する手もある。
こういう事をすると検索のスピードとかにも影響があるかもしれないし、
その場合の検索スピードは「名前」の数との兼ね合いもあるかもしれない。
0x01 : 水泳
0x02 : 走行
0x04 : 暗視
Name | Attribution
A | 0x03
B | 0x05
27:デフォルトの名無しさん
12/12/09 18:49:39.52
Name|A*(水泳?1:0)+(A-1)*(走行?1:0)…1*(暗視?1:0)
28:22
12/12/09 19:02:55.23
>>24
コードじゃなくてテーブルの構成ね
テーブル名(列名1,列名1,・・・・列名n)