代码运行正常,但当作为函数编写时,它不会 [closed]

Code runs correctly but when written as a function it does not [closed]

提问人:Hubert S 提问时间:8/10/2022 更新时间:8/10/2022 访问量:91

问:


这个问题是由一个错别字或一个无法再重现的问题引起的。虽然类似的问题可能在这里成为主题,但这个问题的解决方式不太可能帮助未来的读者。

去年关闭。

目前我正在尝试填补

std::vector<std::vector<char>> vec

我正在使用这部分代码来执行此操作:

std::vector<char> tmp;
for(int b = 0; b < 10; b++){
    tmp.push_back('#');
}
for(int a = 0; a < 10; a++){
    vec.push_back(tmp);
}

在使用以下方法进行测试时,它按预期工作:

std::cout << vec.size() << "\n";
std::cout << vec[0].size() << "\n";

(输出为: 10 30 千米赛 当我尝试将其制作成一个函数时,问题就来了:

void fill(std::vector<std::vector<char>> v, char ch = 0x20) {
        std::vector<char> tmp;
        for(int b = 0; b < 10; b++){
            tmp.push_back(ch);
        }
        for(int a = 0; a < 10; a++){
            v.push_back(tmp);
        }
    }

使用以下方法进行测试时:

fill(vec, '#');
std::cout << vec.size() << "\n";
std::cout << vec[0].size() << "\n";

我收到一个分段错误,如下所示:

0
Segmentation fault (core dumped)

我想 0 表示向量甚至没有被向量填充。我还应该说函数是单独文件中类的成员。如有必要,我可以提供。我找到了这个,但不幸的是,它不是很有帮助。vectmpfill

C++ 函数 向量 C++14

评论

1赞 user253751 8/10/2022
提示:如果我先写再调用,它会改变 x 吗?void f(int i) {i = 7;}f(x);
1赞 NathanOliver 8/10/2022
您按值传递了向量,这将进行复制。您需要通过引用传递:void fill(std::vector<std::vector<char>> v, char ch = 0x20) -> void fill(std::vector<std::vector<char>>& v, char ch = 0x20)
2赞 user12002570 8/10/2022
为什么不直接使用?std::vector<std::vector<char> > vec(10,std::vector<char>(10, '#'));

答:

2赞 john 8/10/2022 #1

超级常见的新手错误。当你想让一个函数计算一些东西时,你应该从函数返回结果,而不是将结果作为参数传递。

喜欢这个

std::vector<std::vector<char>> fill(char ch = 0x20) {
    std::vector<std::vector<char>> v;
    ...
    return v;
}

vec = fill('#');

另一种方法是将对结果的引用传递给函数

void fill(std::vector<std::vector<char>>& v, char ch = 0x20) {
    ...
}

fill(vec, '#');

请注意,额外的内容会变成参考。&v

第一个是可取的(恕我直言),但许多新手更喜欢第二个。我猜是因为它更接近他们最初尝试编写的代码。

评论

0赞 Hubert S 8/10/2022
哇,感谢您的快速回复,谢谢。我重写了它,似乎工作正常,所以再次感谢。
1赞 463035818_is_not_an_ai 8/10/2022
它不仅仅是新手/非新手或个人喜好,而且这两个功能的作用不同。 将向现有向量添加更多元素。第一个只能创建一个新向量,而不能附加到现有向量void fill(std::vector<std::vector<char>>& v, char ch = 0x20)
0赞 john 8/10/2022
@463035818_is_not_a_number是的,这是一个很好的观点,这是更喜欢拳头的另一个原因(假设添加到现有向量不是意图)。
2赞 user12002570 8/10/2022 #2

问题是这是未定义的行为,因为您按值传递了向量,因此仍然是一个空向量。vec[0].size()vec

为了解决这个问题,你可以通过引用传递向量。

//--------------------------------------v----------------------->pass by reference
void fill(std::vector<std::vector<char>>& v, char ch = 0x20) {
    
}

另请注意,您不需要创建和调用函数,因为我们可以直接初始化向量,如下所示:

std::vector<std::vector<char> > vec(10,std::vector<char>(10, '#'))

演示