【C言語】
return(&自動変数)はバグ

warning: function returns address of local variable

警告:関数が自動変数(ローカル変数)のアドレスを返却した
[-Wreturn-local-addr]


■この記事の概要

この記事では、C言語で自動変数のアドレスをreturnする危険性を解説しています。関数終了後に消滅するローカル変数のアドレスを返すと不定動作の原因に。安全な代替案として静的変数の利用や動的メモリ確保が紹介されています。


■自動変数のアドレスをreturnで返却

#include    <stdio.h>
char    *自動変数のアドレス返却(void) 
{
    char    自動変数[] = "自動変数のアドレスを返してはダメ";
    return  &自動変数[0];
}
int main(void)
{
    printf("%s\n",自動変数のアドレス返却());
}

自動変数の領域は関数終了後消滅するので
このアドレスを返却すると消滅してしまった領域を参照する可能性があり参照時何が書かれているかわかりません。

修正案1:
char 自動変数[]を
static char 静的変数[]とする。
欠点は上書きされるので
最後に書き込んだ値だけが有効です。

修正案2:
return 自動変数 ;を
return strdup(自動変数);とする。
欠点は動的に確保した領域なので
解放処理が必要です。


■自動変数アドレスを出力引数に代入

#include    <stdio.h>
void    自動変数のアドレスを出力引数に設定(char **出力引数) 
{
    char    自動変数[] = "出力引数に代入してはダメ";
    *出力引数 = &自動変数[0];
}
int main(void)
{
    char    *name = NULL;
    自動変数のアドレスを出力引数に設定(&name);  
    printf("%s\n",name);
}

現状gcc、clangで検出できない模様


■自動変数アドレスを外部変数に代入

#include <stdio.h>
char    *外部変数ポインタ ;
void    自動変数のアドレスを外部変数に設定() 
{
    char    自動変数[] = "外部変数に代入してはダメ";
    外部変数ポインタ = &自動変数[0];
}
int main(void)
{
    自動変数のアドレスを外部変数に設定();       
    printf("%s\n",外部変数ポインタ);
}

clang –analyzeで検出できます

参考:

DCL30-C. 適切な記憶域期間でオブジェクトを宣言する

https://www.jpcert.or.jp/sc-rules/c-dcl30-c.html

C-FAQ7.5: 呼ばれた関数のローカルな(自動変数の)配列を指していてはいけない。

http://www.kouno.jp/home/c_faq/c7.html#5