このchktype
関数は、スタック上の自動変数にメモリを割り当て、この変数のアドレス (つまり、この変数へのポインタ) を返します。
問題は、スタックに割り当てられた変数がスコープ外になるたびに自動的に破棄されることです (つまり、関数を定義する中括弧の外に制御が渡されます)。
これは、基本的に、無効なメモリ位置へのポインターを返していることを意味します。これは悪いニュースです。C言語では、未定義の動作です。実際には、結果として出力が低下したり、場合によってはクラッシュしたりすることさえあります。
char *chktype(char *Buffer, int Size)
{
// This pointer variable is allocated on the stack, but that's okay because
// it's a pointer to a string literal, which are always constant.
// (Technically, you should add the "const" qualifier to the declaration.)
const char *strng = "Content-Type: ";
int sz;
char *found = strstr (Buffer, strng);
char *found1 = strstr(found, "\r\n");
sz=strlen(found)-strlen(found1);
// Like all the above variables, the one is also allocated on the stack.
// But it's the source of your problem here, because it's the one that
// you are returning at the end of the function.
// Problem is, it goes away at the end of the function!
char type[sz];
strncpy(type, found1, sz-1);
return(type);
}
関数から aを返す正しい方法は、 (または) 関数char*
を使用してヒープから新しいメモリを割り当てることです。これは、関数の呼び出し元が、戻り値によって使用されるメモリを解放する責任があることを意味します。そうしないと、プログラムでメモリ リークが発生します。(この要件は、常に関数のドキュメントに記載してください!「ドキュメント」が宣言の上のコメントを意味する場合でも)。malloc
calloc
たとえば、コードを次のように変更します。
char *chktype(char *Buffer, int Size)
{
// This pointer variable is allocated on the stack, but that's okay because
// it's a pointer to a string literal, which are always constant.
// (Technically, you should add the "const" qualifier to the declaration.)
const char *strng = "Content-Type: ";
int sz;
char *found = strstr (Buffer, strng);
char *found1 = strstr(found, "\r\n");
sz=strlen(found)-strlen(found1);
char *type = malloc(sz); // allocate memory from the heap
strncpy(type, found1, sz-1);
return(type);
}
ここで、chktype
関数の呼び出し側で、free
戻り値の処理が終わったら必ず呼び出すようにする必要があります。
char *type = chktype(...);
// do something
free(type);
堅牢なコードはmalloc
、null ポインターの結果をテストして、要求されたメモリの割り当てに失敗していないことを確認する必要があることに注意してください。その場合、何らかの方法でエラーを処理する必要があります。わかりやすくするために、上には示していません。