2011-12-05 163 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

有問題與這些行:

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

,因爲該值Random返回可以等於s它是超出範圍。 索引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; 
} 

我建議你redine的Random按照以上建議,因爲它是數學聲音說Random生成的值在[nLow, nHigh)範圍內。迪克斯特拉爲此提供了一個合理的論據。閱讀:

順便說一句,你應該參考接受矢量參數。

+1

+1 edsger鏈接 –

+0

這真是我的愚蠢!感謝您指出這一點和鏈接。 –

2

我會說這個問題是你用非法索引訪問你的向量。與其他C和C++數組一樣,矢量的索引從0到1。將您的Random呼叫更改爲Random(0, s - 1)