幼稚園時代「何組」でしたか?

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

エラー内容:セグメンテーション違反
     (実行時のみ、コンパイルエラーはなし)
エラー箇所(多分):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;
}

A 回答 (5件)

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;
 }
}

この回答への補足

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
    • good
    • 0
この回答へのお礼

tailkuppaさん回答ありがとう御座いました!
問題のほうはめでたく解決しました!
サンプルのほう、とっても役に立ちました。
ではでは~。

お礼日時:2002/01/17 01:44

下の者ですが、大ボケをかましてしまいました。


>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で終了している必要がありますのでご注意を
    • good
    • 0

セグメンテーション違反 は確保した範囲外のメモリにアクセスした場合におこります。



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

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

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

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

以上、簡単ですが。

参考URL:http://www.linux.or.jp/JM/html/LDP_man-pages/man …
    • good
    • 0

質問のソースを見た限りでは何も言えないし、tailkuppaさまのプログラムならエラーがないと思われるので、ちょっと余談を。



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

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

ポインタマニアの、はぽるんでした。
    • good
    • 0
この回答へのお礼

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

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

このソースの内容自体には、おかしいところは無いと思います。


Lookup()を呼び出している個所とのインタフェースか、または
実引数の定義部分の問題でしょう。
    • good
    • 0
この回答へのお礼

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

いつかまた自分の質問(救援信号ともいう)を見つけたら
その時はまた宜しくお願いします!
では失礼をば♪♪

お礼日時:2002/01/17 01:44

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!