2016-01-29 25 views
-5

我是C++的新手,我有一个问题(抱歉,如果它是基本的东西,但我想知道)。所以我有这个代码是应该一个向量的每个元素乘以一个数字:C++中的向量分段错误

#include<iostream> 
#include "IntCell.h" 
#include<vector> 
using namespace std; 

vector<float> MatMult(int a, vector<float> & b) 
{ 
vector<float> c; 
int i; 
for(i=0;i<=b.size();i++){ 
    c[i]=b[i]*a; 
} 
return c; 

} 

int main() 


{int a=3; 
vector<float> b{1,2,3,4,5}; 
vector<float> c = MatMult(a,b); 
cout<<c[2]; 
} 

它编译罚款,但我得到段错误:11.什么是错的呢? 谢谢!

+1

你应该重复** **之前b.size(),因为向量0索引 – Incomputable

+0

检查线在'for',你要计算是不是你真的想计算一下。 – tkausl

+0

你从未初始化过'c'。 – NathanOliver

回答

2

vector<float> c;创建一个空向量。您然后在c[i]=b[i]*a;中使用它,这是未定义的行为,因为c[anything]不存在。

如果您想使用c[i]=b[i]*a;,您需要使cb尺寸相同。这将是这样的:

vector<float> MatMult(int a, vector<float> & b) 
{ 
    vector<float> c(b.size()); 

    for(int i = 0; i < b.size(); i++){ 
//     ^use < here since b[b.size()] is out of bounds 
     c[i]=b[i]*a; 
    } 

    return c; 
} 
+0

谢谢。就是这样。 – SSSJ

+0

@SSSJ没问题 – NathanOliver

2

你不能只做c[i],因为目前还没有这样的索引。你最好写c.push_back(b[i] * a)或预先分配内存c.reserve(b.size())

更重要的是,b.size()返回元素的数量在一个载体,而不是最大指数,所以你应该使用i < b.size(),而不是i <= b.size()

+1

他/她正在做我<= b.size()-1,非常规但没有错误 – ForeverStudent

+2

@ForceBru:在你的防守中,问题首先没有'-1'。 –

+1

@LightnessRacesinOrbit,当讨厌者以这种暴力的方式改变他们的问题时,我讨厌它。把它卷起来。 – ForceBru

1

除了其他的答案给出,发现马上一个方式,如果你正在访问向量出界是首先开发使用vector::at(),而不是使用[]

vector<float> MatMult(int a, vector<float> & b) 
{ 
    vector<float> c; 
    int i; 
    for(i=0;i<=b.size();i++){ 
     c.at(i) = b.at(i) * a; 
} 
return c; 

而是分段错误,你会被给予out_of_range异常,从而给你的问题是什么更多的信息。一旦你摆脱了所有的out_of_range错误,你可以切换到使用[]

Live Example using vector::at

+0

@NathanOliver:No. –

+0

@LightnessRacesinOrbit当然是啊。异常弹出窗口仍然有异常类型。 – NathanOliver

+0

@NathanOliver:我不知道什么是“异常弹出”,但是如果你不处理这个异常,那么你的程序将被终止,任何值得它的salt的调试器都可以用来确定它是什么异常举起等 –

3

如果你有一个较新的编译器,这是简单的。按值取vector,并使用基于范围的for循环以避免超出范围的错误。

vector<float> MatMult(int a, vector<float> b) 
{ 
    for (float& value : b) { 
     value *= a; 
    } 
    return b; 
} 

这可以作为模板函数更通用。注意下面的代码几乎肯定可以改进。

template <typename T> 
vector<T> MatMult(int a, vector<T> b) 
{ 
    for (auto& value : b) { 
     value *= a; 
    } 
    return b; 
} 
+0

为什么''''自动'为了使它更容易在将来改变? – NathanOliver

+0

@NathanOliver:我可能把它作为模板,然后使用'auto'。 – Blastfurnace

+0

@NathanOliver:如果'b'发生了变化,那么你的函数在语义上已经发生了变化,因此你可能希望被迫记住重新读取函数以确保没有其他东西需要改变。 'auto'阻止编译器执行这些最基本的编译器活动。循环被设计为在'float'上运行,所以写'float'! –