weemiee
@weemiee (weemiee)

Are you sure you want to delete the question?

Leaving a resolved question undeleted may help others!

【C言語】char型の関数で文字列を返したい

Q&A

Closed

次のCプログラムについて質問です。

#include <stdio.h>
#include <string.h>

char *str_connect(int m){
	
	char buf_len[20];
	char str_current[1000]="ABC,";
	char str[100];
	
	for(int i=1;i<=m-1;i++){
		fgets(buf_len,sizeof(buf_len),stdin);
		sscanf(buf_len,"%s",str);
		strcat(str_current,str);
		strcat(str_current,",");
	}
	
	fgets(buf_len,sizeof(buf_len),stdin);
	sscanf(buf_len,"%s",str);
	strcat(str_current,str);
	strcat(str_current," etc...");
	return str_current;
	
}

int main(){
	
	int n;
	char buf[20];
	
	fgets(buf,sizeof(buf),stdin);
	sscanf(buf,"%d",&n);
	printf("%s",str_connect(n));
	
}

こちらが期待していたのは、標準入力で

4
DEF
GHI
JKL
MNO

のように入力すると

ABC,DEF,GHI,JKL,MNO etc...

と出力されるプログラムで、上のプログラムでは確かに期待通りに実行されています。しかし、実行環境によっては、実行時にstr_connect関数のreturn文の箇所に⚠️がついている(出力結果は正しい)ので、気になっています。
この問題の原因を特定出来ず、困っています。文字列の返し方が間違っているのでしょうか?

0

3Answer

str_currentが関数内のローカル変数だとからでは?

ローカル変数は関数終了時に破棄されるので、たまたま期待した値が読めたとしてもそれは運の問題でしょう。

>文字列の返し方が間違っているのでしょうか?
str_currentを関数の外部で定義するのではいかが?

1Like

自動変数が占有していたメモリ領域をスコープ外から参照していることによります.

順を追っていくと,おそらくプログラム実行中に次のことが起きます.


char str_current[1000]="ABC,";

関数 str_connect は自動変数として配列 char str_current[1000] を作る.これはメモリ上のどこかに格納される.

return str_current;

関数 str_connect は,配列 char str_current[1000] の先頭を指すポインタを返す.
自動変数である配列 str_current[1000] はスコープを抜けるので,それが占有していたメモリ領域は解放される.(メモリ上のかつて str_current[1000] があった場所は,もしかしたら解放前の内容がそのまま入っているかもしれないし,まったく異なるでたらめなデータが入っているかもしれない.)

printf("%s",str_connect(n));

関数 printfstr_connect が返したポインタを見て,その指示先に存在するであろう文字列を出力する.しかし,指示先の領域は既に解放されているので,そこに目的の文字列に相当するデータが入っていることは保証されない.


解決手段はいくつか考えられますが,str_current[1000] の宣言に static をつけるのが簡便だと思います.これにより,配列の内容がスコープ外でも維持されるようになります.

static char str_current[1000]="ABC,";
1Like

@usa3usaさん、@satomineさん、ご回答ありがとうございます。
char str_current[1000]="ABC,";をstr_connect関数の外で定義」と「char str_current[1000]="ABC,";のchar部分をstatic charに変更」、どちらの方法で実行しても⚠️が出なくなりました!
お二人にアドバイス頂き、非常に助かりました。個別に、@satomineさんに紹介頂いたstaticについて色々と調べてみようと思います。

0Like

Your answer might help someone💌