2016-09-01 6 views
-2

topcoderで見つかった古い問題を解決しようとしています。私はすぐに文字列の配列の要素の数を見つけることに取り組んでいます。ここに私のコードです文字列配列の要素数をカウントする際にセグメンテーションエラーが発生するC++

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

using namespace std; 

class MiniPaint { 
private: 
    size_t numLines;  

public: 
    int leastBad(string picture[], int maxStrokes) { 
     numLines = 0; 
     while (!picture[numLines].empty()) { 
      numLines++; 
     } 

     cout << numLines << '\n'; 


     return 0; 
    } 

}; 


int main() { 

    MiniPaint instance; 
    string picture[] = {"BBBBBBBBBBBBBBB", "WWWWWWWWWWWWWWW", "WWWWWWWWWWWWWWW", "WWWWWBBBBBWWWWW"}; 


    instance.leastBad(picture, 10); 
    return 0; 
} 

このコードは私にセグメンテーションフォールトを与えます。何かが間違っている、コードは要素の数を数える機能のために少し過剰ですが、私はクラスを拡張してより多くの機能を追加したいと思っています。誰かがここで間違っていることを説明できるなら、私は感謝します!前もって感謝します。

編集:私は、whileループで

cout << picture[numlines] << '\n'; 

によってコードを展開配列の実際の要素を示すために、最初の4つの適切な文字列が表示され、その後、何らかの形でそれが無限端にスペースを印刷。だから、問題は

picture[4].empty() 

は絵だけで四つの要素を持っているにもかかわらず、trueを返していないという事実のどこかにあります。

+1

実際に配列の最後を読み込むための 'empty()'文字列はありません。 –

+0

picture [4]は5番目の要素を返します。これは配列にはありません。 C/C++配列のインデックスは0から始まります。あなたは未知のメモリにアクセスしています。プログラムは文字列であり、実際にはそうではないことを示すempty()関数を呼び出しています。 –

+0

文字列リテラルから作成された配列だけに自動的に終了標識が与えられます。 – molbdnilo

答えて

5

あなたwhileループ条件は、アレイ内の最後の文字列が空であることを前提としています

int leastBad(string picture[], int maxStrokes) { 
    numLines = 0; 
    while (!picture[numLines].empty()) { 

しかし、(メインで定義されている、あなたの入力文字列配列)がではありません空の""文字列で終了しました。

ですから、この空の文字列の終端を追加することもできます。

// inside main() 

string picture[] = {..., "" /* Empty string terminator */ }; 

また、現代のC++では、私は一般的にstd::vector<std::string>、代わりに生のCスタイルの配列の配列コンテナクラスにを使用することをお勧めしたいです。

この場合、size()メソッドを使用して配列サイズ(つまり要素数)を取得するか、配列全体を繰り返し処理する範囲指定ループを使用できます。

+0

ありがとう、私は本当にあなたが言及したようなコンテナクラスを使用することを好むでしょう。しかし、これは私が解決しようとしているトップコーダの問題です。ここでは入力の種類は私のものではありません。 https://community.topcoder.com/stat?c=problem_statement&pm=1996&rd=4710 – Slugger

+0

@Slugger問題の要件はJava用に策定されています。 C++でそれを解決したい場合は、それに応じて要件を調整する必要があります。 – molbdnilo

+0

ああ、申し訳ありませんが、それは私の悪かったです。助けてくれてありがとう、答えはまだ私に何をしたかったのかをより多くの洞察を与えてくれました。 – Slugger

0

あなたはpicture[numLines]の配列境界にありません。配列の長さを渡すか、それを計算してインデックスnumLinesをチェックする必要があります。コードは次のようになります。

size_t length = sizeof(picture)/sizeof(*picture); // For VS use _countof macro 
while (numLines < length && !picture[numLines].empty()) 
{ 
    ++numLines; 
} 
+0

コメントをいただきありがとうございますが、これは私が事前に要素の数を知っている必要がありますか? – Slugger

+0

@Slugger主なことは長さを確認することです。長さを計算することができます。この質問をチェックする - [配列の長さはどうすればわかりますか](http://stackoverflow.com/questions/4108313/how-do-i-find-the-length-of-an-array) – Nikita

0

範囲外の配列にアクセスします。

picture[4]に電話すると、終了していない文字列オブジェクトにアクセスしたい場合は、関数empty()の呼び出しが初期化されていないメモリにあります。

あなたはどちらかnumLines<=3までの配列がどのように大きな保存および反復処理する必要があるか、ベクトルを使用することができます

std::vector<std::string> picture = ... 

for(std::string line : picture) 
{ 
    //do stuff 
} 
+0

ありがとうコメントのために、これは私が事前に要素の数を知っている必要がありますか? – Slugger

+0

はい。それがネイティブ配列の欠点です。この問題を避けるためにベクターがあります。彼らは内部配列を持っていて、そこにいくつの要素があるのですか? – Hayt

関連する問題