-1

私はこれについてあまりにも長い間頭を悩ませてきました。C ループ内でランダム生成を処理する方法について多くのトピックを見てきましたが、2 つのループが関係している場合は何も見ていません。

以下は私のコードです:

typedef struct
{
    char qh_uid[6];
    long int qh_vd;
    long int qh_pd;
    long int qh_id;
    double qh_value;
}quote_history;

int records_size = 20;
int batch_size = 5;

char *rand_str(char *dst, int size)
{
    static const char text[] = "abcdefghijklmnopqrstuvwxyz"
                               "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
    int i, len = size;
    for ( i = 0; i < len; ++i )
    {
        dst[i] = text[rand() % (sizeof text - 1)];
    }
    dst[i] = '\0';
    return dst;
 }

char *rand_tstp(char *dst, int size)
{
    static const char text[] = "0123456789";
    int i, len = size;
    for ( i = 0; i < len; ++i )
    {
        dst[i] = text[rand() % (sizeof text - 1)];
    }
    dst[i] = '\0';
    return dst;
}

double randfrom(double min, double max)
{
    double range = (max - min);
    double div = RAND_MAX / range;
    return min + (rand() / div);
}

quote_history *feed_batch(quote_history *qh_batch, int batchsize)
{
    int j;
    char mytext[6];
    char mylong[17];
    for (j = 0; j < batchsize; ++j)
    {
        quote_history qh_aux;
        printf("uid : %s - value : %lf\n",rand_str(mytext, sizeof mytext), randfrom(0,100000));
        strcpy(qh_aux.qh_uid, rand_str(mytext, sizeof mytext));
        qh_aux.qh_vd = strtol(rand_tstp(mylong, sizeof mylong), NULL, 10);
        qh_aux.qh_pd = strtol(rand_tstp(mylong, sizeof mylong), NULL, 10);
        qh_aux.qh_id = strtol(rand_tstp(mylong, sizeof mylong), NULL, 10);
        qh_aux.qh_value = randfrom(0,100000);
        qh_batch[j] = qh_aux;
    }
    printf("--------------\n");
    return qh_batch;
}

int
main(int           const argc,
     const char ** const argv) {

    quote_history *subArray;

    srand(time(NULL));
    int k;
    for (k = 0; k < (int)(records_size/batch_size); ++k) {
        subArray= (quote_history*)calloc(batch_size, sizeof(quote_history));
        subArray = feed_batch(subArray, batch_size);
        // Do something with subArray
        free(subArray);
    }
}

基本的に、私がやりたいことは、いくつかの値にランダムな生成がある struct quote_history のバッチを (配列として) 生成し、次にバッチを処理して別のものに移動することです。

何らかの理由で、ランダム生成は feed_batch 関数内でうまく機能しますが、ループ内の次のアイテムに移動すると、バッチは常に同じままになります。

コードの結果を貼り付けるのを忘れました:

uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------
uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------
uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------
uid : qJfzrJ - value : 64938.995598
uid : LyCadK - value : 23030.096583
uid : dcOicU - value : 26016.211568
uid : BmpSTV - value : 76145.000279
uid : aQvABq - value : 92286.726130
--------------

多くの組み合わせ (たとえば、feed_batch 関数の代わりにループ内でループ) を試しましたが、成功しませんでした。

誰かが私を助けてくれることを願っています。

フロリアン

4

2 に答える 2

1

私があなたのコードを理解していれば、あなたが見逃しているのは、ランダムに生成された文字列を構造体の配列にコピーすることですqh_uid。実際、コピーする必要はありません。構造体のバッファーに直接ランダムな文字列を生成できます。

quote_history *feed_batch(quote_history *qh_batch, int batchsize)
{
    int j;
    for (j = 0; j < batchsize; ++j)
    {
        rand_str(qh_batch[j].qh_uid, sizeof(qh_batch[j].qh_uid) - 1);
        printf("uid : %s - value : %lf\n", qh_batch[j].qh_uid, randfrom(0,100000));
    }
    printf("--------------\n");
    return qh_batch;
}

また、Sander De Dycker がコメントで述べていることは true です。 に書き込むことはできません。書き込むことがqh_uid[6]できる最大値は ですqh_uid[5](これを行うことで、アラインメントの考慮事項はさておき、実際には の最初のバイトを上書きしていますqh_vd)、配列を覚えておいてくださいインデックスは から始まり0ます。したがって、-1に渡されるサイズに が追加されrand_strます。

割り当てに関する vlad_tepesch の回答も検討してください。

于 2013-06-18T15:29:10.483 に答える
1

メインは quote_history の 1 つのフィールドを割り当て、for ループで解放します。

feed_batch はこのポインタを受け取り、配列であるかのようにアクセスします --> デバッガはメモリ アクセス エラーを報告するはずです。

新しい推測:
私はあなたがそれが機能すると思う理由を知っています(printfsは正しいです)が、外部では機能しません。しかし、コードが欠落しているため、これは推測にすぎません。構造体に mytext ポインターを保存していると思います。最後に、すべての配列要素が同じ文字列を指しています。さらに悪いことに、その文字列は、feed_batch を終了した後にスコープを失う自動変数です。

ところで:
なぜダイナミック アロケーションが必要なのですか? quote_history のオブジェクトを宣言し、そのポインタを渡すだけです。または quote_history オブジェクトの配列を宣言します。ここでは動的割り当ては必要ありません。

于 2013-06-18T15:04:09.357 に答える