2011-12-05 17 views
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 ([email protected]) at test_write.cc:74 
#3 0x0000000100003cf5 in main (argc=1, argv=0x7fff5fbff998) at test_write.cc:49 

なぜ文字列の割り当てが失敗しますか?私は、メモリリークのためにこの問題が発生している人がいることを知りました。しかし、ここではそうは思われません。何か不足していますか?

答えて

3

これらのラインに問題があります。 インデックスretの最大値はs-1です。

だから、解決策がある、どちらかあなたはこの記述:

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

か、とRandom定義:それは数学的であるので、上記の提案として、私はあなたがRandomをredineすることをお勧め

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

Random[nLow, nHigh)の範囲の値を生成します。 Dikkstraはこのための賛成論を提供しています。これを読む:ところで

は、あなたが参照によってベクトル引数を受け入れる必要があります。

+1

edsgerのリンク –

+0

+1私はかなり愚かでした!これとリンクを指摘してくれてありがとう。 –

2

違法インデックスであなたのベクトルにアクセスしているということです。ベクトルは、他のCおよびC++配列と同様に、0からsize-1までのインデックスを持ちます。 Randomの電話番号をRandom(0, s - 1)に変更してください。

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

Random戻りが範囲外であるsに等しい可能性があるため値:

関連する問題