vector 在 C++ 中包含超出其大小的额外值
vector contains extra values beyond its size in c++
我有一个结构向量,该结构是值的三元组。
struct Process
{
int64_t id, arrivalTime, burstTime;
};
vector<Process> parseInputFile(string filename, vector<Process> &vec){
ifstream inFile;
int64_t arrival;
int64_t burst;
inFile.open(filename);
if (!inFile) {
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
for ( int64_t i = 0; i>=0; i++) {
inFile >> arrival;
inFile >> burst;
if(inFile.eof()){
inFile.close();
cout<<"Size of vector: "<<vec.size()<<endl;
return vec;
}
vec.push_back({i, arrival, burst});
}
return vec;
}
int main(int argc, char * const argv[]){
string algo = argv[1];
string filename = argv[2];
int timeSlice;
vector<Process> vec;
vec = parseInputFile(filename, vec);
for(int i = 0; i <vec.size()+10; i++){
cout<<vec[i].arrivalTime<<" "<<vec[i].burstTime<<endl;
}
}
正如您在上面看到的,在 for 循环中,我打印出超出矢量大小的 10 个值,这就是我得到的输出
1 10
3 5
5 3
0 0
51841 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
即使我的文件只有前 3 行。
在我未来的代码中,我希望能够在这个向量中查找值并移动它们,如果我的向量充满垃圾,这是不可能的。
如何确保我的矢量仅填充我提供给它的输入文件中的值?
正如评论中提到的,您不能只读取超出向量分配 space 的内存而不要期望垃圾。您的 RAM 看起来有点像这样(非常简单):
Address | Value
--------|-------
0x00001 | garbage
0x00002 | 1 <--- vector vec points here (vec[0])
0x00003 | 2
0x00004 | 3 <--- three elements were pushed, so vector vec ends here (vec[2])
0x00005 | garbage
因此,如果您阅读超过 vec[2]
,您将在 RAM 中读取未定义的随机值。这就是为什么您会在 for 循环中看到垃圾。
顺便说一下,如果上面的图表对你来说很陌生,你可能应该阅读一些 C/C++ 教程或阅读一本书。
最后,我不确定你到底想达到什么目的,但是如果你想保证你的向量结束后的10个值都是0,那么你必须将这些值初始化为0。C++赢了神奇地为你做到这一点。
您可以使用 vec.reserve(N)
执行此操作,其中 N 是您要初始化的元素数。
此外,就像提到的评论一样,您应该按引用而不是按值传递向量。按照你的方式,向量在传递给你的函数时被复制,函数修改它并且 returns 修改后的副本。看看下面的代码,其中传递了向量的地址,函数直接修改了向量而不需要复制(节省内存并且速度更快)。
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
struct Process
{
int64_t id, arrivalTime, burstTime;
};
// note the & sign means will pass vec by reference instead of by value
void parseInputFile(string filename, vector<Process>& vec){
ifstream inFile;
int64_t arrival;
int64_t burst;
inFile.open(filename);
if (!inFile) {
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
for ( int64_t i = 0; i>=0; i++) {
inFile >> arrival;
inFile >> burst;
if(inFile.eof()){
inFile.close();
cout<<"Size of vector: "<<vec.size()<<endl;
break;
}
vec.push_back({i, arrival, burst});
}
}
int main(int argc, char * const argv[]){
string algo = argv[1];
string filename = argv[2];
int timeSlice;
vector<Process> vec;
// initialize and zero 30 elements
vec.reserve(30);
// modify vec by passing it by reference
parseInputFile(filename, vec);
for(int i = 0; i <vec.size()+10; i++){
cout<<vec[i].arrivalTime<<" "<<vec[i].burstTime<<endl;
}
}
我有一个结构向量,该结构是值的三元组。
struct Process
{
int64_t id, arrivalTime, burstTime;
};
vector<Process> parseInputFile(string filename, vector<Process> &vec){
ifstream inFile;
int64_t arrival;
int64_t burst;
inFile.open(filename);
if (!inFile) {
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
for ( int64_t i = 0; i>=0; i++) {
inFile >> arrival;
inFile >> burst;
if(inFile.eof()){
inFile.close();
cout<<"Size of vector: "<<vec.size()<<endl;
return vec;
}
vec.push_back({i, arrival, burst});
}
return vec;
}
int main(int argc, char * const argv[]){
string algo = argv[1];
string filename = argv[2];
int timeSlice;
vector<Process> vec;
vec = parseInputFile(filename, vec);
for(int i = 0; i <vec.size()+10; i++){
cout<<vec[i].arrivalTime<<" "<<vec[i].burstTime<<endl;
}
}
正如您在上面看到的,在 for 循环中,我打印出超出矢量大小的 10 个值,这就是我得到的输出
1 10
3 5
5 3
0 0
51841 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
0 0
即使我的文件只有前 3 行。 在我未来的代码中,我希望能够在这个向量中查找值并移动它们,如果我的向量充满垃圾,这是不可能的。 如何确保我的矢量仅填充我提供给它的输入文件中的值?
正如评论中提到的,您不能只读取超出向量分配 space 的内存而不要期望垃圾。您的 RAM 看起来有点像这样(非常简单):
Address | Value
--------|-------
0x00001 | garbage
0x00002 | 1 <--- vector vec points here (vec[0])
0x00003 | 2
0x00004 | 3 <--- three elements were pushed, so vector vec ends here (vec[2])
0x00005 | garbage
因此,如果您阅读超过 vec[2]
,您将在 RAM 中读取未定义的随机值。这就是为什么您会在 for 循环中看到垃圾。
顺便说一下,如果上面的图表对你来说很陌生,你可能应该阅读一些 C/C++ 教程或阅读一本书。
最后,我不确定你到底想达到什么目的,但是如果你想保证你的向量结束后的10个值都是0,那么你必须将这些值初始化为0。C++赢了神奇地为你做到这一点。
您可以使用 vec.reserve(N)
执行此操作,其中 N 是您要初始化的元素数。
此外,就像提到的评论一样,您应该按引用而不是按值传递向量。按照你的方式,向量在传递给你的函数时被复制,函数修改它并且 returns 修改后的副本。看看下面的代码,其中传递了向量的地址,函数直接修改了向量而不需要复制(节省内存并且速度更快)。
#include <iostream>
#include <vector>
#include <fstream>
using namespace std;
struct Process
{
int64_t id, arrivalTime, burstTime;
};
// note the & sign means will pass vec by reference instead of by value
void parseInputFile(string filename, vector<Process>& vec){
ifstream inFile;
int64_t arrival;
int64_t burst;
inFile.open(filename);
if (!inFile) {
cerr << "Unable to open file datafile.txt";
exit(1); // call system to stop
}
for ( int64_t i = 0; i>=0; i++) {
inFile >> arrival;
inFile >> burst;
if(inFile.eof()){
inFile.close();
cout<<"Size of vector: "<<vec.size()<<endl;
break;
}
vec.push_back({i, arrival, burst});
}
}
int main(int argc, char * const argv[]){
string algo = argv[1];
string filename = argv[2];
int timeSlice;
vector<Process> vec;
// initialize and zero 30 elements
vec.reserve(30);
// modify vec by passing it by reference
parseInputFile(filename, vec);
for(int i = 0; i <vec.size()+10; i++){
cout<<vec[i].arrivalTime<<" "<<vec[i].burstTime<<endl;
}
}