OKWAVEのAI「あい」が美容・健康の悩みに最適な回答をご提案!
-PR-
解決
済み

たすけて!

  • すぐに回答を!
  • 質問No.199418
  • 閲覧数497
  • ありがとう数6
  • 気になる数0
  • 回答数5
  • コメント数0

お礼率 82% (19/23)

こんにちは(こんばんわ?)。
わたしは某大学の学生です。
現在課題のためにプログラムを制作中なのですが、
どうしてもエラーが消えなくて困っています。
提出期限がすでに切れているので、大至急お答え願います!たすけてー!

エラー内容:セグメンテーション違反
     (実行時のみ、コンパイルエラーはなし)
エラー箇所(多分):strcmpの使い方?

ソース(一部):
(前略)
int Lookup(char *p[],char buffer[])
{
int i;

for(i=0;i< parray_size;i++)
if(!strcmp(p[i],buffer))
break;

if(i== parray_size)return 0;
else return 1;
}
通報する
  • 回答数5
  • 気になる
    質問をブックマークします。
    マイページでまとめて確認できます。

質問者が選んだベストアンサー

  • 回答No.2
レベル9

ベストアンサー率 53% (52/98)

1. #include <string.h> は入っていますか?
 今回は問題ないけど、引数が間違っていたりするときに参考になるので、入れておいた方が無難ですよ。

2. parray_size はちゃんと p のサイズになっていますか?
 というか、どこで宣言していますか?
 これがp の配列数より大きいと質問のようなエラーになりそうです。

3. この関数(Lookup)を呼んでいる箇所のソースが欲しいです。
 そっちで間違っている可能性のほうがありそう。

4. とりあえず、下記のような感じで動くことを確認しました。

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

int parray_size = 3;

int
main(void) {

 static char *p[3] = { "ほげ", "ふが", "もげ" };
 char buffer[10];

 printf ("%d\n", Lookup(p, "ない"));
 printf ("%d\n", Lookup(p, "ほげ"));

}

int Lookup(char *p[],char buffer[])
{
 int i;

 for (i=0;i< parray_size;i++) {
  if (!strcmp(p[i],buffer)) {
   break;
  }
 }

 if (i== parray_size) {
  return 0;
 }
 else {
  return 1;
 }
}
補足コメント
swd21c

お礼率 82% (19/23)

1.string.hは入ってます。

2.parray_sizeはプリプロセッサで、
  #define parray_size 10000
  の様に、定義しています。

3.これが呼び出し部分です。
  /*(前略)*/  
void main(void)
{
  char *p[parray_size];
  char buffer[parray_size];
  /*(中略)*/  
  printf("What's a word to lookup? ");
  
  scanf("%s",buffer);
  
  if(Lookup(p,buffer))
    printf("%s is exist.\n\n", buffer);
  else printf("%s is not exist.\n\n", buffer);
}
投稿日時 - 2002-01-16 22:08:02
お礼コメント
swd21c

お礼率 82% (19/23)

tailkuppaさん回答ありがとう御座いました!
問題のほうはめでたく解決しました!
サンプルのほう、とっても役に立ちました。
ではでは~。
投稿日時 - 2002-01-17 01:44:44
-PR-
-PR-

その他の回答 (全4件)

  • 回答No.1
レベル13

ベストアンサー率 24% (357/1463)

このソースの内容自体には、おかしいところは無いと思います。 Lookup()を呼び出している個所とのインタフェースか、または 実引数の定義部分の問題でしょう。 ...続きを読む
このソースの内容自体には、おかしいところは無いと思います。
Lookup()を呼び出している個所とのインタフェースか、または
実引数の定義部分の問題でしょう。
お礼コメント
swd21c

お礼率 82% (19/23)

ranxさん回答ありがとう御座いました!
問題のほうはめでたく解決しました!

いつかまた自分の質問(救援信号ともいう)を見つけたら
その時はまた宜しくお願いします!
では失礼をば♪♪
投稿日時 - 2002-01-17 01:44:38
  • 回答No.3
レベル12

ベストアンサー率 40% (230/562)

質問のソースを見た限りでは何も言えないし、tailkuppaさまのプログラムならエラーがないと思われるので、ちょっと余談を。 char *p[] という引数の定義ですが、このように書くように推奨されてはいるものの、意味があいまいになりかねないので char **p を私はオススメします。 どちらも同じ表現ですが、人間から解釈すると前者は配列のポインタを渡し、後者はポインタのポインタを渡すと解 ...続きを読む
質問のソースを見た限りでは何も言えないし、tailkuppaさまのプログラムならエラーがないと思われるので、ちょっと余談を。

char *p[]
という引数の定義ですが、このように書くように推奨されてはいるものの、意味があいまいになりかねないので
char **p
を私はオススメします。
どちらも同じ表現ですが、人間から解釈すると前者は配列のポインタを渡し、後者はポインタのポインタを渡すと解釈できます。
しかし、実際に内部では、ポインタのポインタが渡されているのです。

焦っているのに余談なんて失礼しました。
配列とポインタは似通っていて、ポインタを要求されるところでは配列を渡すことができる場合が多いのですが、多次元になるとそれが通用しない場合があります。
二次元配列、ポインタの配列、配列のポインタ、ポインタのポインタ、これらは混同しやすいので微妙に使い分けることが重要です。

ポインタマニアの、はぽるんでした。
お礼コメント
swd21c

お礼率 82% (19/23)

はぽるんさん回答ありがとう御座いました!
問題のほうはめでたく解決しました!

tailkuppaさんのサンプルを元に試行錯誤。
その結果、今まで*p[]の初期化に

  for(i=0;i < parray_size;i++)
   p[i]=NULL;

のようにヌルポインタを使っていたものを、

  for(i=0;i < parray_size;i++)
   p[i]="\0";

の様にしたらスッパリ解決しました。
………なんででしょ?(笑)
はぽるんさんはポインタに詳しいんですよね?

結局strcmpはあんまり関係なかったようです…
んー…Cは奥が深いっす。
それではこのへんで~。
投稿日時 - 2002-01-17 01:45:17
  • 回答No.4
レベル9

ベストアンサー率 33% (33/98)

セグメンテーション違反 は確保した範囲外のメモリにアクセスした場合におこります。 このプログラムで、考えられるのは  1. parray_size が p 用に確保されたサイズより大きく、ループ内で、p[i] が範囲外をさしている  2. strcmp は、いずれかが、'\0' まで探索をします。 つまり、このプログラムで、pもしくは、bufferの末尾に'\ ...続きを読む
セグメンテーション違反 は確保した範囲外のメモリにアクセスした場合におこります。

このプログラムで、考えられるのは

 1. parray_size が p 用に確保されたサイズより大きく、ループ内で、p[i] が範囲外をさしている
 2. strcmp は、いずれかが、'\0' まで探索をします。
つまり、このプログラムで、pもしくは、bufferの末尾に'\0'が含まれていなければ、探索は範囲外に及ぶ
 3. p、buffer のいずれかに、NULL が渡されている。

の可能性です。
1の対策は、他の部分を見ないことには、、、
2の対策ですが、strncmpという関数がありますので、ご検討下さい。
3の対策は、関数の最初にポインタのチェックを加えることです。

まず、どの箇所で、落ちているのかを確認してください。
fprintf(stderr, ".."); // .. には何か好きなメッセージ
で、ポイントポイントで、メッセージを出力し、何処まで表示されたかを確認するのが簡単で、効果的な方法です。

以上、簡単ですが。
  • 回答No.5
レベル9

ベストアンサー率 33% (33/98)

下の者ですが、大ボケをかましてしまいました。 >2の対策ですが、strncmpという関数がありますので、ご検討下さい。 これですが、buffer の大きさをstrlenで求めて(これを例えば、buf_sizeとします)、 for(i=0;i< parray_size;i++) を for(i=0;i< parray_size-buf_size;i++) にすればOKですね… ...続きを読む
下の者ですが、大ボケをかましてしまいました。
>2の対策ですが、strncmpという関数がありますので、ご検討下さい。
これですが、buffer の大きさをstrlenで求めて(これを例えば、buf_sizeとします)、
for(i=0;i< parray_size;i++)

for(i=0;i< parray_size-buf_size;i++)
にすればOKですね…

後、parray_sizeも同様にstrlenで求めた方が安全ですね^^;
速度が重要でなければ、strlenで計算する方をおすすめします。
strlenも\0で終了している必要がありますのでご注意を
このQ&Aで解決しましたか?
関連するQ&A
-PR-
-PR-
こんな書き方もあるよ!この情報は知ってる?あなたの知識を教えて!
このQ&Aにはまだコメントがありません。
あなたの思ったこと、知っていることをここにコメントしてみましょう。

その他の関連するQ&A、テーマをキーワードで探す

キーワードでQ&A、テーマを検索する
-PR-
-PR-
-PR-

特集


いま みんなが気になるQ&A

関連するQ&A

-PR-

ピックアップ

-PR-
ページ先頭へ