vector<int> vec;
boost::scoped_array<int> scpaInts;
scpaInts.reset(new int[10]);
for (int i=0; i<10; i++)
scpaInts[i] = i*2;
vec.assign(&scpaInts[0], &scpaInts[9]+1); // => method one
vec.assign(scpaInts.get(), scpaInts.get()+10); // => method two
Run Code Online (Sandbox Code Playgroud)
问题1>我找到了两种方法.但我不确定它们是否正确或有更好的方法来做到这一点.
问题2>我们无法从boost :: scoped_array获取有效长度吗?
谢谢
我有C++代码处理来自一个1800元素阵列的三个连续值.由ICC 14.0编译的代码比MSVC生成的代码慢约68%(1600对2700 CPU周期).我不明白为什么.有人可以帮忙吗?即使我设置英特尔编译器-O3开关,它也不会改变时序.CPU是Ivy Bridge.
#include <iostream>
int main(){
int data[1200];
//Dummy-populate data
for(int y=0; y<1200; y++){
data[y] = y/2 + 7;
}
int counter = 0;
//Just to repeat the test
while(counter < 10000){
int Accum = 0;
long long start = 0;
long long end = 0;
int p = 0;
start = __rdtsc();
while(p < 1200){
unsigned int level1 = data[p];
unsigned int factor = data[p + 1];
Accum += (level1 * factor);
p = p + 2; …Run Code Online (Sandbox Code Playgroud) 我需要能够访问(只读,不涉及调整大小或类似的东西)一个std::vectorvia指针的元素.例如,
std::vector<int> foo(10);
int *ptr_begin = &foo[0];
Run Code Online (Sandbox Code Playgroud)
到目前为止一切顺利,这保证在当前标准(23.3.6.1)中有效:
向量的元素是连续存储的,这意味着如果v是一个向量,其中T是某种类型而不是bool,那么它服从所有0 <= n <v的身份&v [n] ==&v [0] + n .尺寸().
因此,我们可以使用指针访问向量的所有元素,因为它们存储在连续的内存块中.但是那个过去最后一个元素呢?我的意思是,执行此操作是合法的吗?
int *ptr_end = ptr_begin + foo.size()
Run Code Online (Sandbox Code Playgroud)
(注意,我不是试图访问过去的最后一个值,只是为了定义一个指向它的指针 - 等同于foo.end()你喜欢的).该标准仅提到通过指针算术访问元素,但显然我们不访问任何元素.
(作为旁注,过去最后一些东西的存在的定义似乎与数组的基本概念紧密相关(参见例如5.7/5),但在整个标准中,它似乎是连续存储的概念和数组可以互换使用.我读错了吗?)
我不相信这是重复的(见下文)。†
我发现这个问题几乎是一个精确的重复,但是我认为答案无法分析漏洞。请参阅:*((*(&array + 1))-1)`是否可以安全地用于获取自动数组的最后一个元素?
我知道通常的方法是计算sizeof(array)/sizeof(*array)以获取数组中元素的数量。(并且在注释中已向我指出C ++具有std::size(array)。)
因此,我认为如果可以到达最后一个元素之后的地址,则可以使用指针数学运算来计算该数字。但是,后来我想到我可以:
&array + 1
Run Code Online (Sandbox Code Playgroud)
但是,此值的类型是指向数组的指针,因此要使数学正常工作,我需要取消引用此值。
const auto N = *(&array + 1) - array;
Run Code Online (Sandbox Code Playgroud)
在C和C ++中是否有允许这种取消引用合法的津贴?
我知道您可以指向数组最后一个元素之后的一个,但是您不能取消引用它。但是,此取消引用会产生一个数组对象,该对象立即衰减为指向其第一个元素的指针。
我可以使用a reinterpret_cast来避免使用取消引用运算符,但是我想知道在这种情况下C和/或C ++语言是否允许取消引用。
†我错过了类似的问题,但是这个问题有细微的不同。我已经了解了代码的工作原理,并且了解了将指针从数组的最后一个元素后移去通常存在问题。我要问的是,数组对象在表达式中使用时会衰减为指针的事实是否允许例外。我认为这可能是因为,取消引用指向对象的指针通常会导致对象值本身在表达式中使用(如果对象不存在,这将是一个问题)。
说我有一个像这样的数组:
int val[10];
Run Code Online (Sandbox Code Playgroud)
我故意用从负值到任何高于9的值来索引它,但没有以任何方式使用结果值.这可能是出于性能原因(也许在进行数组访问后检查输入索引会更有效).
我的问题是:
例如
struct A
{
static vector<int> s;
};
vector<int> A::s = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)
但是,我的编译器不支持初始化列表.有什么办法可以轻松实现吗?lambda函数在这里有用吗?
它似乎有具体采取的地址语言一个超过数组结束.
如果没有被解雇,为什么在结束时2或2,000,000会成为问题?
看一些简单的循环:
int array[];
...
for (int i = 0: i < array_max; ++i)
{
int * x = &array[i *2]; // Is this legal
int y=0;
if (i * 2 < array_max) // We check here before dereference
{
y = *x; // Legal dereference
}
...
}
Run Code Online (Sandbox Code Playgroud)
为什么或在什么时候这变得不确定,在实践中它只是将ptr设置为某个值,为什么如果它没有被重新引用它将是未定义的?
更具体地说 - 除了预期会发生什么之外,还有什么例子?
在C++ Primer的第2章"变量和基本类型"中,它说:
指向对象的指针和指向不同对象末尾的指针可以保持相同的地址.
我不是母语人士,我认为这就是为什么我对句子"一个指针越过一个对象的结尾"感到有点困惑.有人会告诉我这意味着什么吗?
编译器在编译代码时出现分歧
int main()
{
constexpr int arr[3] = {};
static_assert((void*)(arr + 3) == (void*)(&arr + 1));
}
Run Code Online (Sandbox Code Playgroud)
在 GCC 和 Clang 中,static_assert不会触发,MSVC 认为static_assert失败https://godbolt.org/z/dHgmEN
应(void*)(arr + 3) == (void*)(&arr + 1)评估为true,为什么?
具体来说,考虑以下代码:
uint8_t my_array[3] = { 1, 2, 3 };
uint8_t *my_array_a = my_array;
uint8_t *my_array_b = nullptr;
uint8_t *my_element1 = &my_array_a[0];
uint8_t *my_element2 = &my_array_b[0];
Run Code Online (Sandbox Code Playgroud)
请注意,这些类型都没有什么特殊之处operator&。operator*
如果这是 C,则标准保证my_array_b + 0在计算期间不会取消引用my_element2(来自 ISO/IEC 9899:TC2,运算符的语义&):
类似地,如果操作数是运算符的结果
[],则不会计算运算符或the 隐含的&一元,结果就像删除了运算符并将 the更改为运算符一样。*[]&[]+
C++ 标准是否提供类似的保证(至少对于给定的场景),或者以my_element2这种方式进行计算在技术上是未定义的行为,因为它涉及取消引用nullptr?
据我所知,上面的代码片段中没有隐藏的 UB。强制转换nullptrtouint8_t*是合法的,并且nullptr + 0被明确定义为 Yieling nullptr。诚然,这个样本也不是很有用,但无论如何我们都是在做规则律师。
这个问题类似于通过下标获取最后一位数组元素的地址:C++标准是否合法?,但我特别感兴趣的是 C++ 中是否也存在&[]->+ …