これは確かなコードではありませんが、どこかでアドレスのコピー(ポインター)を渡し、COPYに変更を加えた(mallocのように)と思われます。このアドレスのアドレス(ポインター上のポインター)を渡す代わりに、実際にはポインターを変更し、そのコピーの1つは変更しません。
私が話していることを説明するための例:
int dostuff(char* str)
{
str = malloc(sizeof(char));
str[0] = 0x42;
return 1; // size of string.
}
int main(int argc, char** argv)
{
char* mystr = NULL;
unsigned int strlength = 0;
strlength = dostuff(mystr);
printf("%s\n", mystr); // Segfaults here: mystr == NULL.
free(mystr);
return 0;
}
だからここに何が起こっているのですか:
- NULLに設定された新しいcharポインタを作成します(たとえば、再割り当てする場合に適しています)。
- その値(NULL)をに渡します
dostuff
。この関数は、この値のコピーを(char *型で)作成し、このコピーを変更します。
- printfは印刷のためにmystrにアクセスし、NULL [0](0)から読み取ろうとしているときに、セグメンテーション違反を起こします。
main
もちろん、残りは実行されません。
誰かがその落とし穴に陥る理由は次のとおりです。通常、関数でポインタを使用して変更を行う場合は、アドレスではなくコンテンツを変更します。アドレスを変更すると、ほとんどの場合(このような場合を除いて)、新しいアドレスを返すようにアドレスを変更する関数があります。のようにaddress = malloc(size)
。
一方、POINTERを設定したい場合(明らかにコンテンツではない場合)、そのアドレスのコピーを関数に渡す必要があります。上記のコードの動作バージョンは次のとおりです。
int dostuff(char** str)
{
(*str) = malloc(sizeof(char));
(*str)[0] = 0x42;
return 1; // size of string.
}
int main(int argc, char** argv)
{
char* mystr = NULL;
unsigned int strlength = 0;
strlength = dostuff(&mystr);
printf("%s\n", mystr); // Now works: mystr is allocated.
free(mystr);
return 0;
}
したがって、覚えておいてください。疑わしい場合は、ポインタを返し、他の変数のアドレスを取得してください(strlength
ここ)。不可能な場合は、操作しているデータの実際のタイプに十分注意し、変更後にアドレスを再確認してください。
お役に立てば幸いです。