gpt4 book ai didi

c++ - 错误:数组下标高于 std::vector::insert 的数组边界

转载 作者:行者123 更新时间:2023-11-28 02:02:48 25 4
gpt4 key购买 nike

我正在编译 -Werror并发现转换为错误的警告:

1>  cc1plus.exe: warnings being treated as errors
1> c:\rtems-4.9\bin\../lib/gcc/powerpc-rtems4.9/4.3.2/include/c++/bits/stl_vector.h: In function 'int someFunc()':
1> D:\Git\Error_Parsing_script\Src\Plus\RTEMS_proj\c:\rtems-4.9\bin\..\lib\gcc\powerpc-rtems4.9\4.3.2\include\c++\bits\stl_vector.h(1043,1) : error: array subscript is above array bounds

来自这段代码:

struct ControllerConfigDataType1 {
char name[50];
int controllerType;
};

int someFunc()
{
std::vector<char> reply;
reply.reserve(255);
ControllerConfigDataType1 response = { { 0 } };
reply.insert(reply.end(), reinterpret_cast<char*>(&response), reinterpret_cast<char*>(&response) + sizeof(response));
return 0;
}

据我所知,this code is completely valid .一件奇怪的事情是,如果我手动设置 sizeof(resonse)到 <= 50(char 数组的大小)那么我们就不会出错。似乎这个错误来自于试图超出 char name[50] 的范围response 中的数组,我想这从我的指针取消引用中是有意义的 reinterpret_cast<char*>(&response) + sizeof(response) .

知道ControllerConfigDataType1的格式不能改变,有没有办法满足编译器对这一行的保留?

请注意,这是来自 RTEMS 4.9.2 的一个有点旧的编译器(请参阅下面的详细信息),这可能意味着此警告不会出现在较新版本的 GCC 中(并且不会出现在 Visual C++ 中) VS2015)。

其他信息

错误提到stl_vector.h(1043,1)这是 std::vector::insert 的实现功能:

  // Called by the range insert to implement [23.1.1]/9
template<typename _InputIterator>
void
_M_insert_dispatch(iterator __pos, _InputIterator __first,
_InputIterator __last, __false_type)
{
typedef typename std::iterator_traits<_InputIterator>::
iterator_category _IterCategory;
_M_range_insert(__pos, __first, __last, _IterCategory());
}

从库中检索到的缩进

请注意,编译器由 RTEMS 4.9.2 提供并具有以下版本信息:

Thread model: rtems
gcc version 4.3.2 (GCC)

最佳答案

获取对象字节的一个好方法是使用memcpy,并让字节类型为unsigned char。这很好,因为 Holy Standard 至少有一个这样的例子,所以如果一个编译器在它上面窒息,那么很容易说,嘿,这个编译器在标准的一个例子上窒息,让我们停止使用它。即使 ISO 标准中的示例是非规范的。


您的原始示例,采用这种方法:

int someFunc1()
{
std::vector<unsigned char> reply;
reply.reserve(255); // Note: this, from original example, is only an optimization.
ControllerConfigDataType1 response = { { 0 } };
// reply.insert(reply.end(), reinterpret_cast<char*>(&response), reinterpret_cast<char*>(&response) + sizeof(response));
int rs = reply.size(); int ds = sizeof(response); reply.resize(rs+ds); memcpy(&reply[rs], &response, ds);
return 0;
}

此代码假定 int 足以满足此处使用的 vector 的大小,这对于网络数据包来说是合理的:它不可能是 2 GB 或更多。否则将 int 替换为 ptrdiff_t。可能重命名为 Size


更一般地说,您可以将其抽象化并集中化,这有助于测试和维护,如下所示:

#include <stddef.h>     // ptrdiff_t
#include <string.h> // memcpy
#include <type_traits> // std::is_trivially_copyable
#include <utility> // std::enable_if_t

using Byte = unsigned char;
using Size = ptrdiff_t;

template< class Type
// The following sanity-check line must be removed for a C++03 compiler:
, class Enabled_ = std::enable_if_t< std::is_trivially_copyable< Type >::value >
>
void append_to( std::vector<Byte>& v, Type const& o )
{
Size const n_v_bytes = v.size();
Size const n_o_bytes = sizeof( o );
v.resize( n_v_bytes + n_o_bytes );
memcpy( &v[n_v_bytes], &o, n_o_bytes );
}

关于c++ - 错误:数组下标高于 std::vector::insert 的数组边界,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38749361/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com