
No.6ベストアンサー
- 回答日時:
ひとつ気になった点があります。
#1の補足にあるコードには、MONTH_RECの「定義」がありません。
そして、alloc_Month()では
> Month= (MONTH_REC *)malloc(sizeof(struct Month_t));
とかやってますけど、
MONTH_REC と struct Month_t って本当に同じものですか?
あと、alloc_Monthの実装も
使ってない変数 int iがある一方で、引数で貰ってきた
ものを変数として使いまわしているし
ちょっと首を傾げたくなる書き方です。
MONTH_REC*
alloc_Month2(MONTH_REC *Month)
{
/* MONTH_REC *p = (MONTH_REC *)calloc(1, sizeof (struct Month_t)); */
MONTH_REC *p = (MONTH_REC *)calloc(1, sizeof (MONTH_REC));
MONTH_REC *q = Month;
if (!p) {
Exit(ERROR,__FILE__,__LINE__);
}
if (!q) {
Month_top = p;
}
else {
q->after = p;
}
Month_end = p;
return p;
}
のような感じに書き換えたらどうなります?
#あーqはいらなかったか。
あ、もうひとつ追加。
>alloc_Month()関数はNULLではありませんでしたが、strcpy(Month->Data,(char *)Data.arr);
>手前でMonth->Dataをチェックしてみると
「Bad Address」とメッセージが返されてしまいました
とありますが、この strcpyの実行直前の
Month を %p 書式で出力したときの値と、
これを割り当てた alloc_Monthのなかでの
memset(Month,NULL,sizeof(struct Month_t));
の前後での Monthを%p出力したときの値は
全部同じ値になってますか?
Month_tの定義では
typedef struct Month_t MONTH;
struct Month_t{
struct Month_t *after;
char Data[8+1];
};
なので、Monthが正しい値である場合に Month->Dataが
変な値(0?)になることはないと思いますが?
No.5
- 回答日時:
64bit環境の場合、0とNULLとのとり違いが致命的になりうる場合があります。
初級C言語Q&A(3)
http://www.st.rim.or.jp/~phinloda/cqa/cqa3.html
の
Q 【関数呼び出しの0】
関数呼び出しの引数としてヌルポインタを書く場合、0と書いてはいけないと言われた。
[その他] BINARY HACKS - COLUN++ BLOG
http://d.hatena.ne.jp/colun/20061203
NULLと0は等しい?
あたりにその辺に絡んだ話があります。
詳しくは
Binary Hacks ―ハッカー秘伝のテクニック100選: 本: 高林 哲,鵜飼 文敏,佐藤 祐介,浜地 慎一郎,首藤 一幸
http://amazon.jp/dp/4873112885
のHACK#49「64ビット環境で0とNULLの違いに気を付ける」
を読んでみてください。
ただ考え直すとmemsetは可変引数をとる関数じゃないし、
プロトタイプ宣言がちゃんとされていればキャストがかかるだろうし、
予測は外してるっぽいのには違いありませんが。
データモデルとは?
http://www.oklab.org/language_c/lp64.html
No.4
- 回答日時:
私のコードの読み違いなら申し訳ないのですが、
alloc_Month()関数で、
if(!Month){
Exit(ERROR,__FILE__,__LINE__);
}
としているため、Month != NULL の場合は必ず Exit してしまいます。
結果、alloc_Month()関数の戻り値は必ず NULL なのではないでしょうか?
Month = NULL の場合の
memset(Month,NULL,sizeof(struct Month_t));
の動作は試していないのでどうなるのか分かりませんが。。
Month = NULL で戻ってきているため、直後の
strcpy(Month->Data,(char *)Data.arr);
でセグメンテーションフォルトになります。
Month が NULL になっている原因は分かりませんが、
alloc_Month()関数での malloc() が失敗すると戻り値が NULL となり、
Month に NULL が代入されてしまうこともありえます。
また少し質問とは外れますが、上記 memset() の第2引数が NULL は問題ないと思います。
ほとんどの処理系では、 stdio.h の中で
#define NULL 0
と定義されています。HP-UX も同様だと思います。
NULL か 0 か '\0' かは、結局同じ値になるので、
私はコードの視認性を考え、その場に応じた書き方をするようにしています。
この回答への補足
alloc_Month()関数はNULLではありませんでしたが、strcpy(Month->Data,(char *)Data.arr);
手前でMonth->Dataをチェックしてみると「Bad Address」とメッセージが返されてしまいました。尚、今は
memset(Month,NULL,sizeof(struct Month_t));
のNULLは一応、0に置き換えています。
No.3
- 回答日時:
ここまで状況が絞り込めているのなら、デバッガでステップ実行すれば
すぐに場所をピンポイントで特定できそうな気がするんですが、
実は毎回発生するわけじゃなくて何かの拍子にSEGVが起きるとかだったりします?
とりあえず共有メモリ領域を他のスレッドやプロセスがぶっ壊しているという
可能性はないとして、
Month= (MONTH_REC *)alloc_Month(Month);
strcpy(Month->Data,(char *)Data.arr);
↑このalloc_Monthの呼び出し後に毎回SEGVしているということでいいですか?
一つだけ気になる部分があります。
alloc_Monthの中で
>memset(Month,NULL,sizeof(struct Month_t));
というのがありますが、HP-UXって64ビットOSですよね?
HP-UXのccがILP64なのかLP64なのか、はたまたLLP64なのかは知りませんが
memsetの第二引数に NULL を渡しているのはまずいような気がします。
関数にしようとしては int を期待しているのにポインタを渡しているわけですから。
#もちろんそれで問題ない場合もありますが
Digital UNIXでは発生していなかったということですので(たしかこれも
64ビットOSでしたよね?)あんまり自信はありません。
もしなんらかの理由でデバッガでステップ実行を試せないのなら、
alloc_Monthのところどころ(先頭とリターン直前の部分と、memsetの
前後くらいかな)で
データがおかしくなっていないかチェックしてみてください。
Data.arrは見るのが大変でしょうが、Monthもぶっ壊れているということですから
とりあえずこちらだけでも。
この回答への補足
アドバイスありがとうございます。
alloc_Monthの呼び出し後に毎回必ずSEGVしています。
memset(Month,NULL,sizeof(struct Month_t));
がおかしいとは思っていませんでした。NULLの部分を変更して実行してみます。
No.1
- 回答日時:
そのstrcpyでSEGVしているんなら、パラメータの値をチェックしました?
多分移植前のシステムでは正常動作していたってのは勘違いで、
未初期化のポインタを使ってたりしていたのがたまたま動いていただけで
HP-UXに持ってきたときにバグが顕在化しただけじゃないですか?
つか助けろって言われたってたったそれだけの情報じゃ無理だって。
この回答への補足
以下今回のコードです。
<Month.h>
typedef struct Month_tMONTH;
struct Month_t{
structMonth_t*after;
charData[8+1];
};
MONTH *Get_Month_top();
<Month.c>
staticMONTH_REC *alloc_Month();
staticMONTH_REC*Month_top;
staticMONTH_REC*Month_end;
int Read_Month()
{
EXEC SQL BEGIN DECLARE SECTION;
VARCHAR sqlstmt[4096];
VARCHARData[20];
EXEC SQL END DECLARE SECTION;
MONTH_REC*Month = NULL;
sprintf((char *)sqlstmt.arr,
"SELECT\
D.Data\
FROM \
%s D \
WHERE \
TO_CHAR(D.YEARMONTH,'YYYYMM') = '%s' \
",MONTH,YearMonth);
sqlstmt.len = strlen((char *)sqlstmt.arr);
EXEC SQL WHENEVER SQLERROR GOTO sql_error;
EXEC SQL PREPARE S2 FROM :sqlstmt;
EXEC SQL DECLARE C2 CURSOR FOR S2;
EXEC SQL OPEN C2;
EXEC SQL WHENEVER NOT FOUND DO break;
while(1){
EXEC SQL FETCH C2 INTO
:Data;
Data.arr[Data.len] = NULL;
Month= (MONTH_REC *)alloc_Month(Month);
strcpy(Month->Data,(char *)Data.arr);
}
EXEC SQL WHENEVER NOT FOUND CONTINUE;
EXEC SQL CLOSE C2;
EXEC SQL WHENEVER SQLERROR CONTINUE;
sql_error:
Sql_Error(__FILE__,__LINE__);
Sql_Rollback(__FILE__,__LINE__);
Exit(ERROR,__FILE__,__LINE__);
return -1;
}
MONTH_REC *alloc_Month(MONTH_REC *Month)
{
inti;
if(!Month){
Month= (MONTH_REC *)malloc(sizeof(struct Month_t));
Month_top = Month;
}else{
Month->after= (MONTH_REC *)malloc(sizeof(struct Month_t));
Month = Month->after;
}
if(!Month){
Exit(ERROR,__FILE__,__LINE__);
}
memset(Month,NULL,sizeof(struct Month_t));
Month_end = Month;
return Month;
}
MONTH *Get_Month_top()
{
return Month_top;
}
パラメータの値ですが、不思議なことにalloc_Month関数の前までは"111"など正常値が入っているのですが、戻ってくるとData.arrが0x000x00x00に変化してしまいます。またMonthも0x00になってしまいます。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- Android(アンドロイド) Androidの最下段のアイコンが移動できません。 AQUOS sense6 を買いました。ドコモで 1 2022/09/20 09:22
- 国民年金・基礎年金 20代女性です。障害年金について教えてください。 当方、2019年に肝臓移植をしており、障害年金2級 1 2022/09/15 14:19
- Excel(エクセル) Excel2010 VBAが特定動作で実行出来なくなる 7 2022/12/29 14:26
- Visual Basic(VBA) excel vbaでselenium basic 3 2022/10/02 12:35
- Windows 10 パソコンが使えず困ってます!(Microsoftアカウントでログイン後、PINコードに関するエラー) 2 2023/03/17 19:09
- その他(悩み相談・人生相談) 日常生活を送ることさえも困難な障害(身体、精神)を抱えた人に対して「大変だね」「障害を抱えているのに 4 2023/06/29 19:39
- 子育て 正常発達の子でも乳幼児健診で引っかかったり、運動面や言葉など成長が平均より遅い場合はありますか? 乳 2 2023/08/27 07:59
- 福祉 障害福祉サービスについて 1 2022/07/29 22:04
- 英語 Bone augmentation for the correction of dehiscence 1 2022/12/31 23:35
- 発達障害・ダウン症・自閉症 発達障害者からも何かしら否定批判されやすく健常者からも責められやすいという、21歳の発達障害のいとこ 7 2023/07/31 18:57
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
VBAで変数定義を変更する方法
-
ビット演算について
-
C++でデータの途中から読み込み
-
16進数のバイト数
-
FORTRANのCOMMONについて
-
#pragmaについて
-
Schemeのコンストラクタの引数は?
-
この型変換の内容がわかりませ...
-
errorC2228 CColorDialog
-
C++変数宣言時のコンストラクタ...
-
C言語のプログラムの流れについて
-
ExcelVBAで初期値のセット
-
メッセージキュー
-
デフォルトコンストラクタで分...
-
「 VBA の 宣言 」 がない場合...
-
変数の初期化について
-
整数から16進数への変換 現在c...
-
Pythonです。 monster ballを定...
-
VBAのプログラムで、DIAG = 1# ...
-
文字列の検索&排除をするプロ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
VBAのプログラムで、DIAG = 1# ...
-
Integer変数をカラにしたいので...
-
「#undef」と「#define」の使い...
-
C言語 構造体の中に共用体を定...
-
構造体のデータを丸ごとコピー...
-
VBAの変数のデータ型を変更する...
-
日付チェック関数について
-
整数から16進数への変換 現在c...
-
typedefをプログラム中で解除す...
-
値が代入されてない時
-
C++ 構造体の一括初期化 {0}
-
VBAで符号無し整数
-
long型のデータをバイト型の配...
-
変数の初期化について
-
1バイトデータの読み出しについて
-
charとucharの違い
-
VBAにてcolorindexを変数に格納...
-
異なる構造体のデータのコピー
-
構造体を型の異なる構造体に代入
-
構造体にする理由・利点・使用例
おすすめ情報