【问题标题】:Changing vector in function by pointer通过指针更改函数中的向量
【发布时间】:2018-09-08 11:02:52
【问题描述】:

cpp新手,不明白怎么回事:

void addElem(vector<someCustomByteType> *result, string str_to_add) {
  someCustomByteType *elem = (someCustomByteType*)str_to_add.data();
  int elem_size = str_to_add.size();
  memcpy(&(*result).back(), elem, elem_size);
}
int main(int argc, _TCHAR* argv[])
{
  vector<someCustomByteType> vec(5);
  vector<someCustomByteType> *vec_ptr = &vec;
  addElem(signed_string_ptr, "abcd");
  return 0;
}

外面,里面:

向量外部没有改变。但 memcpy 有效。这是怎么回事? 谢谢!

【问题讨论】:

  • 请发一个合适的minimal reproducible example。除此之外,我建议您在编译时启用 allextra 警告。看看会带来什么。
  • memcpy 覆盖现有内存。它不会向向量添加新内存。
  • back() 返回对向量中最后一个元素的引用,然后memcpy 继续覆盖它后面的内存中的所有内容,破坏所有可见的内容。只有幸运才能防止您的代码崩溃。
  • @user2501323 为什么向量是通过指针的方式传给函数的?
  • @StoryTeller,按你说的编辑。

标签: c++ string pointers vector append


【解决方案1】:

您正在做的是未定义的行为。 std::vectorstd::string 都不是可简单复制的,这是 std::memcpy 的要求。如果你想将 std::string 复制到 std::vector 中,你可以这样做

void addString(vector<unsigned char>& vec, const std::string& str)
{
    vec.assign(str.begin(), str.end());
}

【讨论】:

  • 稍微编辑问题
【解决方案2】:

函数没有意义。

对于初学者来说,不清楚为什么要使用指向向量的指针而不是对向量的引用。

尽管如此,这份声明

vector<unsigned char> vec(5);

不会为向量重新分配内存。它用 5 个零字符初始化向量,这些零字符将附加到函数中的其他字符。

表达式

&(*result).back()

返回对向量最后一个元素的引用。而这个电话

memcpy(&(*result).back(), elem, elem_size);

将尝试覆盖不属于向量的内存。因此,该函数具有未定义的行为。

你可以这样想象这种情况

   vector
|0|0|0|0|0|
        |a|b|c|d|
         string

因此可以看出有人试图将字符“b”、“c”和“d”复制到不属于向量的内存中。

您应该使用类模板std::vector 的方法来追加新元素。

该函数可以如下所示,如演示程序中所示(前提是您要使用指向向量的指针)。

#include <iostream>
#include <vector>
#include <string>

void addElem( std::vector<unsigned char> *result, const std::string &str_to_add ) 
{
    result->reserve( result->size() + str_to_add.size() );
    result->insert( result->end(), str_to_add.begin(), str_to_add.end() );
}   

int main() 
{
    std::vector<unsigned char> vec;
    std::vector<unsigned char> *vec_ptr = &vec;

    addElem( vec_ptr, "abcd" );

    for ( auto c : *vec_ptr ) std::cout << c;
    std::cout << std::endl;

    return 0;
}

它的输出是

abcd

【讨论】:

  • 终于明白了vector不能和自定义类型一起使用。会尝试另辟蹊径
猜你喜欢
  • 2011-06-23
  • 1970-01-01
  • 2016-06-14
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 2014-06-05
  • 2017-11-24
相关资源
最近更新 更多