2011-12-05 131 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)