0

を呼び出すと、現在セグメンテーション違反 (セグメンテーション違反: 11) が発生していますnewUnitID()

私が間違っていることはわかりません。

これは、関数があるヘッダー ファイルです。

#include <iostream>
#include <cstring>
#include <string>
#include <cstdlib>
#include <ctime>
#include <vector>
#ifndef UnitManager
#define UnitManager
using namespace std;

char randomIDChar(){
    static const char alphanum[] =
        "0123456789"
        "!@#$%^&*"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    int stringLength = sizeof(alphanum) - 1;
    srand(time(0));
    for(int z=0; z < 21; z++)
    {
        return alphanum[rand() % stringLength];
    }
    return 1;
}

string newUnitID(){
    vector<char> v;
    for(int i=0; i < 50; i++){
        v[i] = randomIDChar();
    }
    string str(v.begin(),v.end());
    return str;
}

#endif
4

2 に答える 2

6

ベクトルの演算子 [] は既存の要素にアクセスします。新しい要素を作成しません。空のベクトルから開始するので、

v[i] = randomIDChar();

ベクターの終わりを超えてアクセスします。これを次のように変更できます

v.push_back(randomIDChar());

にも問題があることに注意してくださいrandomIDChar。おそらく投稿された関数のいずれかを呼び出す前に、乱数ジェネレーターを1回だけシードする必要があります。与えられたシードは、予測可能な「乱数」のストリームを生成します。time(0)秒数を返すため、1 秒以内に行うすべての呼び出しは同じシードを持つため、後で呼び出したときに同じ数が生成されますrand

于 2013-11-01T23:15:03.477 に答える
1
v[i] = randomIDChar();

配列の境界 (以前に割り当てられていないベクトルの内部バッファー) の背後にある文字を書き込もうとするため、未定義の動作が発生します。

また、後で文字列を作成するために文字のベクトルが必要ないことにも注意してくださいstd::string。オブジェクトを直接操作できます。また、文字の位置を生成する方法がかなり歪んだ結果を生成することにも注意してください。これにより、より良い結果が得られます。

char randomIDChar(){
    static const char alphanum[] =
        "0123456789"
        "!@#$%^&*"
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
        "abcdefghijklmnopqrstuvwxyz";
    static int len = 0;
    if (len == 0) {
        srand(time(0));
        len = sizeof(alphanum) - 1;
    }
    int pos = ((double)rand() / ((double)RAND_MAX + 1.0)) * len;
    return alphanum[pos];
}

std::string newUnitID(){
    const int LEN = 50;
    std::string str(LEN, ' ');
    for(int i = 0; i < LEN; i++) {
        str[i] = randomIDChar();
    }
    return str;
}

一見の価値があります: C++ で乱数を生成する最良の方法は何ですか?

于 2013-11-01T23:20:11.903 に答える