我正在尝试为uni项目创建一个随机数生成器。
我正在尝试实现一个函数来获取生成此数字列表的时间段(数字开始重复之前多久)。
当我编译并运行它时,它返回507(这是正确的句号)。
然而,大约50%的时间它会返回分段错误。 不知道发生了什么:
#include<iostream>
#include<fstream>
#include<vector>
#include<math.h>
#include<ctime>
using namespace std;
class Random
{
public:
// Constructor
Random(int a, int b, int m)
{
this->setMagicNumbers(a,b,m);
}
// Function to set the magic numbers of the random number generator
void setMagicNumbers(int a, int b, int m)
{
this->A = a;
this->B = b;
this->M = m;
}
// Function that returns a list of uniformly distributed random numbers
vector<double> GetUniform(int N, double initialValue = time(0))
{
double currentNumber = initialValue;
vector<double> RandomNumbers;
for(int i = 0; i <= N; i++)
{
currentNumber = fmod((this->A*currentNumber) + this->B, this->M);
RandomNumbers.push_back(currentNumber / this->M); // The number is normalised here
}
return RandomNumbers;
}
private:
int A, B, M;
};
class NumberList
{
public:
// Function to add an element to the list
void push(double x)
{
this->v.push_back(x);
}
// Function to pop an element off the list
double pop()
{
if(v.size() > 0)
{
int popped = v.back();
v.pop_back();
return popped;
}
else
{
cout << "Cannot pop element off empty list." << endl;
return 0;
}
return 0;
}
// Function to get the value at a given location on the list
double getAt(int i)
{
return this->v[i];
}
// Function to set the value at a given location on the list
void setAt(int i, double value)
{
this->v[i] = value;
}
// Function to find the size of the list
unsigned int size()
{
return this->v.size();
}
// Function to get the vector itself
vector<double> getvector()
{
return this->v;
}
// Function to set the value of the vector itself
void setVector(vector<double> vec)
{
this->v = vec;
}
// Function to print the list of numbers as coordinates to a data file
void printCoordinates()
{
ofstream data("coordinates.dat");
for(unsigned int i = 0; i <= this->v.size(); i++)
{
data << this->v[i] << " " << this->v[i + 1] << "\n";
}
data.close();
}
// Function to print the list of numbers to the terminal
void print()
{
for(unsigned int i = 0; i <= this->v.size(); i++)
{
cout << this->v[i] << endl;
}
}
// Function to get the period of the list of numbers
int getPeriod()
{
int i = 2;
while(true)
{
if(isPeriod(i) == true)
{
return i;
}
else
{
i = i + 1;
}
}
}
private:
// Vector to hold the values for the list
vector<double> v;
// Function to test if 'i' is the period of the list
bool isPeriod(int i)
{
for(int j = 0; j != (i-1); j++)
{
if(this->getAt(j) != this->getAt(i + j))
{
return false;
}
}
return true;
}
};
int main()
{
Random RandNumGenerator(100,104001,714025); // Create a new random number generator with given magic numbers
NumberList numbers; // Create a blank list of numbers
numbers.setVector(RandNumGenerator.GetUniform(10000)); // Add 10000 random numbers to the list
numbers.printCoordinates(); // Print out the random numbers as coordinates to a data file
cout << numbers.getPeriod() << endl; // Print out the period of the random number list
return 0;
}
提前致谢。
答案 0 :(得分:3)
此行可能会导致问题
for(unsigned int i = 0; i <= this->v.size(); i++)
有了它,你使用size作为最后一个索引,这是溢出,尝试改变它:
编辑:实际改变
for(unsigned int i = 0; i < this->v.size()-1; i++)
在循环中,您正在访问向量的第i + 1个元素。
编辑:
这可能不会导致崩溃,而是创建N个元素而不是创建N + 1
for(int i = 0; i <= N; i++)
为此改变:
for(int i = 0; i < N; i++)
编辑: 修复
#include<iostream>
#include<fstream>
#include<vector>
#include<math.h>
#include<ctime>
using namespace std;
class Random
{
public:
// Constructor
Random(long a, long b, long m)
{
this->setMagicNumbers(a,b,m);
}
// Function to set the magic numbers of the random number generator
void setMagicNumbers(long a, long b, long m)
{
this->A = a;
this->B = b;
this->M = m;
}
// Function that returns a list of uniformly distributed random numbers
vector<double> GetUniform(int N, double initialValue = time(0))
{
double currentNumber = initialValue;
vector<double> RandomNumbers;
for(int i = 0; i < N; i++)
{
currentNumber = fmod((this->A*currentNumber) + this->B, this->M);
RandomNumbers.push_back(currentNumber / this->M); // The number is normalised here
}
return RandomNumbers;
}
private:
long A, B, M;
};
class NumberList
{
public:
// Function to add an element to the list
void push(double x)
{
this->v.push_back(x);
}
// Function to pop an element off the list
double pop()
{
if(v.size() > 0)
{
int popped = v.back();
v.pop_back();
return popped;
}
else
{
cout << "Cannot pop element off empty list." << endl;
return 0;
}
return 0;
}
// Function to get the value at a given location on the list
double getAt(int i)
{
return this->v[i];
}
// Function to set the value at a given location on the list
void setAt(int i, double value)
{
this->v[i] = value;
}
// Function to find the size of the list
unsigned int size()
{
return this->v.size();
}
// Function to get the vector itself
vector<double> getvector()
{
return this->v;
}
// Function to set the value of the vector itself
void setVector(vector<double> vec)
{
this->v = vec;
}
// Function to print the list of numbers as coordinates to a data file
void printCoordinates()
{
ofstream data("coordinates.dat");
for(unsigned int i = 0; i < this->v.size()-1; i++)
{
data << this->v[i] << " " << this->v[i + 1] << "\n";
}
data.close();
}
// Function to print the list of numbers to the terminal
void print()
{
for(unsigned int i = 0; i < this->v.size(); i++)
{
cout << this->v[i] << endl;
}
}
// Function to get the period of the list of numbers
int getPeriod()
{
int i = 2;
while(true)
{
if(isPeriod(i) == true)
{
return i;
}
else
{
i = i + 1;
}
}
}
private:
// Vector to hold the values for the list
vector<double> v;
// Function to test if 'i' is the period of the list
bool isPeriod(int i)
{
std::cout << "trying period " << i << endl;
if (i >= v.size()) return true;
for(int j = 0; j < v.size()-1; j++)
{
if(this->getAt(j) == this->getAt(i + j))
{
std::cout << "value at j " << this->getAt(j) << "value at i+j " << this->getAt(i+j) <<endl;
return true;
}
}
return false;
}
};
int main()
{
Random RandNumGenerator(100,104001,714025); // Create a new random number generator with given magic numbers
NumberList numbers; // Create a blank list of numbers
numbers.setVector(RandNumGenerator.GetUniform(10000)); // Add 10000 random numbers to the list
numbers.printCoordinates(); // Print out the random numbers as coordinates to a data file
cout << numbers.getPeriod() << endl; // Print out the period of the random number list
return 0;
}
答案 1 :(得分:0)
稍微玩了一下,我最初认为你的双打矢量以某种方式被破坏了。我发现,如果你把它的大小调整到你想要的确切值 - 这是一个已知的值 - seg错误停止:
vector<double> RandomNumbers(N); // In GetUniform()
通过gdb
运行它是不确定的,因为它看起来好像堆栈已损坏。我还发现当我更改push_back()
只是为了取0:
RandomNumbers.push_back(0.0);
而不是标准化的数字,即使没有向量的初始大小(上图),它也能正常工作,这表明其中一个变量存在问题。
我还发现如果我将currentNumber
设置为1,比如说,而不是调用fmod()
- 即使是最初的所有内容,我也没有出现seg错误:
currentNumber = 1;
这种情况表明它可能与使用fmod()
有趣的是,然后我完全取消了对push_back
的调用,发现仍然有段错误。对不起,我没有比这更多的帮助,但看起来好像在这个地区某处发生了某种腐败。
答案 2 :(得分:0)
在C++
数组索引中,vector
将来自0..size - 1,并且您在代码内部(GetUniform
内部,printCoordinates
内部误用了它) ,...)除了printCoordinates
中你最后写的this->v[i + 1]
之外,它将被转换为this->v[this->v.size() + 1]
,它是最后一个有效索引之后的2个索引。
但我认为您的错误来源位于getPeriod
和isPeriod
,请查看它从0开始到i - 1
并检查该索引是否与索引{{1}处的项目匹配},所以如果i + j
变为i
且大小为500,那么在更糟糕的情况下,您访问的size() - 1
实际上比上一个有效索引大,您肯定会遇到分段错误。现在解决它检查您的索引并且永远不会超出v[499 + 498]
大小的末尾,这意味着您永远不应该使用索引&gt; vector