returnについての質問です – プログラミング – Home

returnについての質問です
 
通知
すべてクリア

[解決済] returnについての質問です

固定ページ 1 / 2

kan
 kan
(@kan)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

お世話になります。
標記の件ですが、returnの前までは処理が行われているようなのですが、
そこで止まっているようなのです。

このような事象が発生するものとして考えられる原因はありますでしょうか。
ご教授お願い致します。

<コード>
int sub1(unsigned short aa, char bb)
{
int iRet = 0;

for(条件)
{
iRet = sub2( cc, &dd );
printf(%d\n, iRet);
if ( iRet == -1)
{
printf(------NG sub2()\n);
}
printf(------OK sub2()\n);
}

}

int sub2(struct aa, char *bb)
{
//処理・・・

printf(BEFORE RETURN\n, iRet);

return (0);
}

<実行結果>
BEFORE RETURN

(※sub2を呼び出した後のprintfの内容が全く表示されません。)

<環境>
WinXP, .NET


引用未解決
トピックタグ
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 600
 

これ、ちゃんとコンパイルできませんよ。
sub2() 内で iRet にアクセスできませんから。

現象を再現できる最小限の正しいコードを示してください。


返信引用
kan
 kan
(@kan)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

すみません。ご指摘の通りsub2()のiRetは不要ですね。

(誤) printf(BEFORE RETURN\n, iRet);
(正) printf(BEFORE RETURN\n);

上記のような処理で、実行結果として
BEFORE RETURN
しか表示されず、プロセスが上がったままの状態になってしまうのです。


返信引用
たく
 たく
(@たく)
ゲスト
結合: 21年前
投稿: 29
 

ccあるいは、struct aaとはなんぞや?


返信引用
kan
 kan
(@kan)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

ccあるいは、struct aaとはなんぞや?

何度もすみません。
cc,struct aaは、構造体のポインタですが、
これを引数にしたほかの関数では戻ってくるようなので、
関係ないと思われます。
なので、無視していただいてかまいません。

<コード>
int sub1(unsigned short aa, char bb)
{
int iRet = 0;
char dd[5];

for(条件)
{
iRet = sub2( dd );
printf(%d\n, iRet);
if ( iRet == -1)
{
printf(------NG sub2()\n);
}
printf(------OK sub2()\n);
}

}

int sub2(char *bb)
{
//処理・・・

printf(BEFORE RETURN\n);

return (0);
}


返信引用
島
 島
(@島)
ゲスト
結合: 23年前
投稿: 238
 

デバッガーで動作を追ってみたらどうなりますか


返信引用
REE
 REE
(@REE)
ゲスト
結合: 24年前
投稿: 240
 

sub2関数の中で、スタックを破壊していると思われます。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 600
 

> sub2関数の中で、スタックを破壊していると思われます。

そのセンが濃厚ですねぇ。
だから '現象を再現できる最小限の正しいコードを示してください' なのに。


返信引用
PATIO
(@patio)
Famed Member
結合: 4年前
投稿: 2660
 

最低限がどこまでなのか絞り込めないようなら、
いっそのこと全文出してしまった方が問題が少ないと思いますよ。
私もREEさんの意見に賛成ですが、
実際には関数sub2に当たる全ソースを提示してもらわないと
なんともいえません。

あまりにも長いというのであれば問題ですが、
(ひとつの関数がそこまで長いというもの実は問題です。)
それにしたって省略のしかたが的を得ていないために
かえって掲示板を読んでる側を混乱させてしまってます。

掲示板を読んでいる人には公開されていない情報はわかりません。
公開可能な情報は基本的にすべて出してしまった方が無難だと考えてください。


返信引用
L
 L
(@L)
ゲスト
結合: 21年前
投稿: 6
 

呼び出し元に戻らないなら、十中八九はバッファオーバーフローによるスタック破壊な
んだろうね。

デバッガでコールスタックウィンドウを表示して sub2 関数内をステップ実行してみた
ら、どこかでコールスタックから呼び出し元の sub1 関数が見えなくなるんじゃない
の?
したら、その近辺のコードが悪さをしてる、ってことで。


返信引用
kan
 kan
(@kan)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

今、sub2()の //処理・・ 部分を全て削除して適当なまとまりごとにコードを追加してい
ったところ、どうやらsprintf()でとまっているようでした。
(ですが、その下の処理は通っていました。)

これが、指摘されていた、スタックを破壊しているということなのだと思うのですが、
sprintf()でセットしているものが、スタックというものを破壊しているのでしょうか。

最後に、コードを省略したために、混乱させてしまいましてすみませんでした。


返信引用
瀬戸っぷ
 瀬戸っぷ
(@瀬戸っぷ)
ゲスト
結合: 22年前
投稿: 160
 

> これが、指摘されていた、スタックを破壊しているということなのだと思うのですが、
> sprintf()でセットしているものが、スタックというものを破壊しているのでしょうか。

sprintf()の第1引数に渡したバッファはsub2()内のローカル変数ではありませんか?
そして、そのバッファのサイズが小さいのではないでしょうか?
sprintf()自身はバッファのサイズに関しては関知しないので、バッファオーバーランで
sub2()から戻る際のアドレスが入った部分に上書きしてしまったのでしょう。


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 600
 

> どうやらsprintf()でとまっているようでした。(ですが、その下の処理は通っていまし
た。)

> sprintf()の第1引数に渡したバッファはsub2()内のローカル変数ではありませんか?
> そして、そのバッファのサイズが小さいのではないでしょうか?

#include <assert.h>

char buffer[N];
...
int n = sprintf(buffer, ...);
assert( n < N );

とかやってみれば一発でわかりそう。


返信引用
kan
 kan
(@kan)
ゲスト
結合: 22年前
投稿: 11
Topic starter  

sprintf()の第1引数に渡したバッファはsub2()内のローカル変数ではありませんか?
そして、そのバッファのサイズが小さいのではないでしょうか?

変換指定子でサイズを小さくちたところ正常に呼び出し元にもどることができました。
因みに、構造体のaaというメンバは後になって追加したものなのですが、
何か関係ありますでしょうか?

typedef struct stru
{


char aa[5];
}stru;

sub2()
{
unsigned long ss;
stru struG;

sprintf(struG.aa, %05u, ss); //エラーになります。
sprintf(struG.aa, %04u, ss); //呼び出し元に戻ることができました。

return 0;
}


返信引用
επιστημη
 επιστημη
(@επιστημη)
ゲスト
結合: 22年前
投稿: 600
 

関係大アリ。

%05u てことは '5文字分の幅で書け' です。
さらに終端の '\0' が追加されて 6文字。 char aa[5]; では不足します。

だから

int n = sprintf(struG.aa, .... );
assert( n < 5 );

すりゃ一発でわかるって書いたのに。


返信引用
固定ページ 1 / 2

返信する

投稿者名

投稿者メールアドレス

タイトル *

プレビュー 0リビジョン 保存しました
共有:
タイトルとURLをコピーしました