car
と_car
は両方とも配列であり、C で配列を割り当てることはできません (配列が構造体 (または共用体) に埋め込まれていて、構造体の割り当てを行う場合を除く)。
これらは、char の配列へのポインターではなく、char へのポインターの配列でもあります。あなたがコードに書いたものはおそらくあなたが望むものです.MAXINT名までのポインタを配列に格納することができます. ただし、タイプを正しく記述する必要があります - char または char ポインターへのポインターの配列として。
文字の配列へのポインターは次のようになります。
char (*car)[MAXINT];
文字ポインターの配列へのポイント (ありがとう、ブライアン) は次のようになります。
char *(*car)[MAXINT];
MAXINT には注意してください。これは非常に大きな配列になる可能性があります (Linux では、少なくとも 2 31 -1である として<values.h>
定義MAXINT
されます)。INT_MAX
コードは次のようになります。
struct foo
{
int _bar;
char * _car[MAXINT];
}
int foofunc (void * arg)
{
int bar;
char * car[MAXINT];
struct foo thing = (struct foo *) arg;
bar = arg->_bar; // this works fine
car = arg->_car; // this gives compiler errors of incompatible types in assignment
}
bar と car への代入はまったくコンパイルされるべきではありません -arg
はvoid *
. おそらくthing
、何らかの形で使用するつもりだったのでしょう。ブライアンが指摘したように、そこにも問題があります。
次のいずれかが必要です。
int foofunc(void *arg)
{
int bar;
char *car[MAXINT];
struct foo thing = *(struct foo *)arg;
bar = thing._bar; // this works fine
car = thing._car; // this is still an array assignment
...other code using bar and car...
}
またはあなたがしたい:
int foofunc(void *arg)
{
int bar;
char *car[MAXINT];
struct foo *thing = (struct foo *) arg;
bar = thing->_bar; // this works fine
car = thing->_car; // this is still an array assignment
...other code using bar and car...
}
または、確かに:
int foofunc(void *arg)
{
struct foo *thing = (struct foo *) arg;
int bar = thing->_bar; // this works fine
char *car[MAXINT] = thing->_car; // this is still an array assignment
...other code using bar and car...
}
最後に、配列の割り当てを扱います。C では、memmove()
これを行うために合理的に使用できます。
int foofunc(void *arg)
{
struct foo *thing = (struct foo *) arg;
int bar = thing->_bar; // this works fine
char *car[MAXINT];
memmove(car, thing->_car, sizeof(car));
...other code using bar and car...
}
同様の関数memcpy()
は、コピーされる領域が重なっている場合、信頼できるセマンティクスを持っていませんが、memmove()
そうです。memmove()
常に正しく機能するため、常に使用する方が簡単です。memmove()
C++ では、 (または) の使用に注意する必要がありますmemcpy()
。このコードでは十分に安全ですが、その理由を理解するのは簡単ではありません。
ここではポインターをコピーしているだけであることに注意する必要があります。ポインターが指す文字列をコピーしているわけではありません。他の何かがこれらの文字列を変更するcar
と、呼び出し元のコードの変数と経由で表示される値の両方に影響します。
最後のポイント - 今のところ: 関数の引数が ? として必要void *
ですか? struct foo *
関数が代わりに ' ' (または ' ')を取るように宣言されている場合、コードをあらゆる種類の悪用にさらす可能性がありますconst struct foo *
。