C++ 使用std::vector<;是否总是安全的;尺寸&u t>;使用不同的整数类型?

C++ 使用std::vector<;是否总是安全的;尺寸&u t>;使用不同的整数类型?,c++,C++,尝试接收具有未知大值的向量时,我提出了一个我认为完全错误的解决方案:我认为当std::vector的元素先分配给一个小值,然后分配给一个大值时,可能会出现错误或数据丢失,因为整个向量的类型已设置,并且内存中的一些空间已被占用安排好了 但是,以下代码起作用: #include<vector> #include<iostream> #include<typeinfo> int main(){ std::vector<size_t> vec;

尝试接收具有未知大值的向量时,我提出了一个我认为完全错误的解决方案:我认为当
std::vector
的元素先分配给一个小值,然后分配给一个大值时,可能会出现错误或数据丢失,因为整个向量的类型已设置,并且内存中的一些空间已被占用安排好了

但是,以下代码起作用:

#include<vector>
#include<iostream>
#include<typeinfo>

int main(){

    std::vector<size_t> vec;

    // Fixing size and adding small number which 
    // I suppose would set type as a small one, 
    // i.e. int 
    vec.resize(2);
    int i = 0;
    std::fill(vec.begin(),vec.end(),i);    

    // add a big number that should not fit smaller type
    unsigned long long bignum = 18446744073709551614;
    vec.push_back(bignum);

    std::cout<<vec[0]<<" "<<vec[1]<<" "<<vec[2]<<std::endl;
    std::cout<<typeid(vec[0]).name()<<std::endl
    <<typeid(vec[1]).name()<<std::endl<<typeid(vec[2]).name()<<std::endl;

    // cell 0 was already initialized with int, trying to make oveflow
    vec[0] = 18446744073709551613;

    std::cout<<vec[0]<<" "<<vec[1]<<" "<<vec[2]<<std::endl;
    std::cout<<typeid(vec[0]).name()<<std::endl
    <<typeid(vec[1]).name()<<std::endl<<typeid(vec[2]).name()<<std::endl;

    return 1;   
}
所有编译器都安全吗?当我不知道使用的整数类型时,我是否可以自由地使用
向量::
(发送到函数等)?

不,这不安全

它之所以有效,是因为您将
int>=0
size\u t
unsigned
,因此,如果尝试输入负值,则会得到
负值%2**n
,其中n是用于表示无符号类型的位数


向量中的元素是
大小\u t
。用
i
填充时,要求编译器将
int
转换为
size\u t
。这不是“安全的”


这是安全的,因为vec[0]是一个
大小\u t



小心那些被设计用来处理。。。尺寸。因此,可以处理
大小\u t
的最大值不是固定的。如果你想要股票整数。使用。

除了@Stargateur的答案外,最好的便携式赌注是
intmax\u t
uintmax\u t
。它们保证是平台上可用的最大整数类型

也可能有特定于编译器的扩展,例如
\uuuu int128\u t
。提供有关gcc中128位内置的一些信息。请注意,
std::intmax\u t
将stll设置为64位。

vector
表示其条目均为
size\u t
的向量。如果尝试存储的值不是
大小\u t
,则在存储之前,它将被隐式转换为
大小\u t
。如果原始值是[
0
SIZE\u MAX
]范围之外的整数,则可能会导致数据丢失

您的问题表明,您可以想象向量正在存储各种不同类型的对象,但事实并非如此


注:
size\u t
通常表示最大可能可分配单元的大小。也许最好使用更能反映所存储值来源的类型,例如,
uint64\t

应该是安全的。大小\u t实际上是uint32\u t或uint64\u t,甚至uint16\u t,这取决于目标计算机的体系结构。将负值设为unsigned int将不会有未定义的行为。@DUJiaen我的错,我认为这与C类似。但也不“安全”,谢谢!看起来我只是误解了一切,因为我认为:size_t type是sizeof操作符(和offsetof操作符)的结果的无符号整数类型,因此它保证足够大,可以包含系统可以处理的最大对象的大小(例如,8Gb的静态数组)。size\u t类型可能大于、等于或小于无符号int,编译器可能会对其进行假设以进行优化。”这意味着
size\u t
会调整变量大小以包含结果。但它只是一个type@Slowpoke我不明白你是怎么得到“大小”的“在引用的文本之外。不同的系统可能有不同大小的size\u t,但它在程序运行期间不会改变是的,对不起,我确实误解了这一点,并且认为sizeof是以某种方式应用的,以使变量包含数据。gcc通常提供
intmax\u t
为64位,和
int128\u t
作为128位整数类型(不符合标准)@M.M,OP没有指定编译器,但是谢谢,我要补充一点,可能有特定于编译器的扩展
$ ./a.out
0 0 18446744073709551614
m
m
m
18446744073709551613 0 18446744073709551614
m
m
m
vec[0] = 18446744073709551613;