2

区切り文字に遭遇したときに char 配列を複数の char 配列に分割する C++ 関数があります。何らかの理由で、3 番目の分割配列を保存すると、プログラムがクラッシュし、std::bad_alloc 例外が返されることがあります。

char ** explode(const char * arr, const char delim) {
int start, end, curr=0, count=1;
char ** strings;
//Iegūst explodēto stringu skaitu
for (int i = 0; arr[i] != 0; i++) {
    if (arr[i] == delim && i != 0 && arr[i+1] != 0 && arr[i+1] != delim ) { //Nav pirmais, nav pēdējais, nav pa labi vēlviens delimiters
        count++;
    }
}
strings = new char*[count];
start = 0;
for (int i = 0; arr[i] != 0; i++) {
    if (arr[i] == delim || arr[i+1] == 0) {
        if (arr[i] == delim) {
            end = i;
        } else {
            end = i+1;
        }
        if (end-start < 1) {
            start++;
        } else {
            copystring(arr,strings[curr++],start,end-start);
            start = i+1;
        }
    }
}
for (int i = 0; i < count; i++) {
    cout << strings[i] << endl;
}

return strings;
}

//Pārkopē daļu no pirmā char masīva uz otru, no START pozīcijas, līdz GARUMS garumā
void copystring(const char * from, char *& to, const int start, const int garums) {
    int curr=0;
    if (garums < 1 || start > charlen(from)) {
        return;
    }
    to = new char[garums];
    for (int i = start; i < start+garums && from[i] != 0; i++) {
        to[curr++] = from[i];
    }
    to[curr] = 0;
}

どの行ですべてがうまくいかないのかはわかりませんが、次の場所で発生すると思います

to = new char[garums];

CodeBlocks 内でこの行をデバッグしようとしましたが、何らかの理由で、ブレークポイントを使用して変数を追跡すると、アプリケーションは正常に動作し、正しく実行されます。デバッグせずに通常どおり実行した場合にのみクラッシュします...

また、文字列や、fstream と iostream 以外のほとんどすべてのライブラリを使用できないことに注意してください。

編集:new char[garums]パーツをに変更してみましたがnew char[100]、魔法のように機能し始めました。問題は、私がそれを変更したことnew char[10]です。その場合、すべてがまだ機能していました。保存したテキストをコンソールに出力したところ、すべてが適切に保存されました。長い単語を 10 文字の長さの char 配列に保存するにはどうすればよいでしょうか (私がテストしている単語は 10 文字を超えています)。しかし、それを変更するとnew char[1]、再びクラッシュし始めましたが、3回目のループ反復の後でのみ再びクラッシュしました。それで、どういうわけか最初の 2 単語を 1 文字の長さの配列に保存しましたか?

EDIT2:そして今、魔法のようにでも動作し始めましたnew char[garums]. ここで何かが本当に間違っています。誰かアイデアはありますか?

4

3 に答える 3

0

あなたが持っている入力データがわからないので、推測する必要があります:

ここでポインタ配列を割り当てますが、すべてのポインタが初期化されていないことに注意してください。

strings = new char*[count]

次に、コードを解析するときに、curr自由に実行できる変数を使用するため、すべてstrings[]が何らかの値に設定されているかどうか、またはcurrより大きい数値に到達するかどうかは定かではありませんcount

私があなたなら、次のことを確認するために小切手を入れます。

a)currを超えないcount

b) がcurrより小さい値に達した場合count、残りのポインタをnullptr

于 2014-04-27T17:22:22.520 に答える
-1

これはおそらくtotypechar*&ではなくtype であることと関係がありchar*ます。一方、私はこのように C++ をプログラミングしたことはありません (これは C ではないのですか?)。('new' のような) 明示的なメモリ管理を使用することは、ロシアン ルーレットをプレイするのと同じくらい良いことです。

これを行うより標準的な C++ の方法を次に示します。

#include <vector>
#include <string>
#include <iostream>

std::vector<std::string> splitString(std::string& str, char c) {
  std::vector<std::string> substrings;
  while(true) {
    unsigned pos = str.find(c);
    substrings.push_back(str.substr(0,pos));
    if(pos == std::string::npos) break;
    str = str.substr(pos+1);
  }
  return substrings;
}

int main()
{
  char c = '*';
  std::string str = "Some*string*that we need to split*properly*";
  std::vector<std::string> result = splitString(str,c);

  for(unsigned i = 0; i < result.size(); ++i) {
    std::cout << i << ": " << result[i] << "\n";
  }
}

出力:

0: Some
1: string 
2: that we need to split
3: properly
4:
于 2014-04-27T15:30:54.310 に答える