2014-02-24 35 views
2

我正面临一个奇怪的问题:我无法正确地重置(破坏并构造)包含矢量的属性。尝试访问矢量时会导致分段错误。如何重建包含向量的非指针类成员?

这是我的代码(witten在C++ 11中)。我认为我尽可能简化它来强调这个问题,但我可能是错的,对此感到抱歉。 目标是打印两次不同(随机)向量的两次。第一个向量运行良好,第二个向量完全失败,原因不明。

#include <iostream> 
#include <ctime> 
#include <cstdlib> 
#include <vector> 

class A 
{ 
     std::vector<int> n; 

    public : 
     A(); 
     std::string toString() const; 
}; 

A::A() 
{ 
    for (int i = 0; i < 10; i++) 
     n.push_back(std::rand()%10); 
} 

std::string A::toString() const 
{ 
    for (auto i : n) 
     std::cout << i << ' '; 
    std::cout << std::endl; 
} 

class B 
{ 
     A a; 

    public : 
     void resetA(); 
     A getA() const; 
}; 

void B::resetA() 
{ 
    a = A(); 
} 

A B::getA() const 
{ 
    return a; 
} 

int main() 
{ 
    srand(time(NULL)); 

    B b; 
    std::cout << b.getA().toString(); 
    b.resetA(); 
    std::cout << b.getA().toString(); 


    return EXIT_SUCCESS; 
} 

出于某种原因,我想避免指针和动态分配尽可能。它适合我的UML概念。

此外,使用简单的int(无向量)时,此代码运行良好。

谢谢。

+2

@Cyber​​ std :: vector不需要调整大小。 push_back动态增长矢量。事实上,调整大小会使他的矢量长20个项目,并在开始时有10个未初始化的值。你的意思是说保留,但这也是错的 – cppguy

回答

6

你的toString()不会返回任何东西,所以你的程序有未定义的行为(并且,实际上,它返回的是随机垃圾,这当然不是有效的std::string对象)。

也许你想使用字符串流呢?

#include <sstream> 

// ... 

std::string A::toString() const 
{ 
    std::ostringstream s; 
    for (auto i : n) 
     s << i << ' '; 
    s << '\n'; 
    return s.str(); 
} 

Live example

一般来说,编译时最好打开尽可能多的警告。这当然会被报告为警告。对于此特定警告(no-void函数不返回任何内容),我强烈建议将其视为错误。

+0

你是对的,这解决了所描述的问题。我的错。 然而,非简化程序中的问题不幸地来自其他地方。谢谢。 – user1527491