0

ベクトルをファイルに書き込み、ファイルを読み取ってベクトルを再度構築し、ベクトルからランダムな要素を選択する必要がある ns3 アプリケーションを作成しています。これはコードです:

#include <iostream>
#include <fstream>
#include <string>
#include <cassert>
#include "ns3/core-module.h"
#include "ns3/network-module.h"
#include "ns3/internet-module.h"
#include "ns3/point-to-point-module.h"
#include "ns3/applications-module.h"
#include "ns3/mf-helper.h"
#include "ns3/ipv4-static-routing-helper.h"
#include "ns3/ipv4-list-routing-helper.h"
#include "ns3/data-rate.h"

#include "ns3/mobility-module.h"
#include "ns3/wifi-module.h"
#include "ns3/ideal-wifi-manager.h"
#include "ns3/wifi-remote-station-manager.h"
#include "ns3/wifi-mode.h"
using namespace ns3;
using namespace std;

void writeFile(string, vector<string>);
void readFile(string, vector<string> &);
unsigned int Random(int,int);
bool Find(vector<string> , string);
void selectNodes(vector<string>);

vector<string> senders;

int main(int argc, char **argv)
{
    vector<string> vect;
    vect.push_back("10.1.1.1");
    vect.push_back("10.1.1.2");
    vect.push_back("10.1.1.3");
    vect.push_back("10.1.1.4");
    vect.push_back("10.1.1.5");
    vect.push_back("10.1.1.6");
    vect.push_back("10.1.1.7");

    writeFile("data.txt", vect);

    vector<string> ret;
    readFile("data.txt",ret);
    selectNodes(ret);
}

void writeFile(string name, vector<string> vs)
{
    ofstream outfile(name.c_str(), ios::out);
    ostream_iterator<string> oi(outfile, "\n");
    copy(vs.begin(), vs.end(), oi);
}

void readFile(string name, vector<string> &vect)
{   
    ifstream file(name.c_str());
    copy(istream_iterator<string> (file), istream_iterator<string>(), back_inserter(vect));
}

void selectNodes(vector<string> ret)
{
    srand(time(NULL));

    string src;
    string dest;

    unsigned int s= ret.size();
    src = ret[Random(1,s)];
    dest = ret[Random(1,s)];


    while(Find(senders, src))
    {
        src = ret[Random(1,s)];
    }

    while (src == dest)
    {
        src = ret[Random(1,s)];
        if (dest != src)
            break;
    }

    cout << "##Source: " << src << std::endl;
    cout << "##Destination: " << dest << std::endl;

    senders.push_back(src);
}

unsigned int Random(int nLow, int nHigh)
{
    return (rand() % (nHigh - nLow + 1)) + nLow;
}

bool Find(vector<string> senders, string addr)
{
    for(unsigned int i=0;i<senders.size();i++)
        if(senders[i] == addr)
            return 1;
    return 0;
}

このコードはランダムにクラッシュします。これはgdbが言うことです

Program received signal EXC_BAD_ACCESS, Could not access memory.
Reason: KERN_INVALID_ADDRESS at address: 0xfffffffffffffff8
0x00007fff8ad5a220 in std::string::_Rep::_M_grab ()
(gdb) bt
#0  0x00007fff8ad5a220 in std::string::_Rep::_M_grab ()
#1  0x00007fff8ad5a29b in std::string::assign ()
#2  0x0000000100002a31 in selectNodes (ret=@0x7fff5fbff7c0) at test_write.cc:74
#3  0x0000000100003cf5 in main (argc=1, argv=0x7fff5fbff998) at test_write.cc:49

文字列の割り当てが失敗するのはなぜですか? メモリリークが原因でこの問題が発生した人がいることがわかりました。しかし、ここではそうではないようです。何か不足していますか?

4

2 に答える 2

3

これらの行に問題があります:

 src = ret[Random(1,s)];
 dest = ret[Random(1,s)];

返される値は、範囲外の値Randomと等しい可能性があるためsです。インデックスtoの最大値retは ですs-1

したがって、解決策は、次のように書くことです。

 src = ret[Random(1,s-1)];
 dest = ret[Random(1,s-1)];

または、次のように定義Randomします。

unsigned int Random(int nLow, int nHigh)
{
    return (rand() % (nHigh - nLow + 1)) + nLow  - 1;
}

Random上記のように を再定義することをお勧めしRandomます[nLow, nHigh). Dikkstra は、これについて適切な議論を提供しています。これを読む:

ところで、ベクトル引数を参照で受け入れる必要があります。

于 2011-12-05T07:03:45.867 に答える
2

問題は、不正なインデックスを使用してベクターにアクセスすることだと思います。ベクトルには、他の C および C++ 配列と同様に、0 からサイズ 1 までのインデックスがあります。Random通話を に変更しますRandom(0, s - 1)

于 2011-12-05T07:01:17.803 に答える