相关疑难解决方法(0)

如何将数据从`boost :: scoped_array`复制到`std :: vector`

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++ boost stl std

7
推荐指数
1
解决办法
5442
查看次数

英特尔编译器生成的代码比MSVC慢68%(提供完整示例)

我有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)

c++ cpu optimization performance icc

7
推荐指数
1
解决办法
411
查看次数

通过指针vs end()访问std :: vector元素

我需要能够访问(只读,不涉及调整大小或类似的东西)一个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),但在整个标准中,它似乎是连续存储的概念和数组可以互换使用.我读错了吗?)

c++ pointers c++11

7
推荐指数
1
解决办法
998
查看次数

指针数学获取数组的长度

我不相信这是重复的(见下文)。


我发现这个问题几乎是一个精确的重复,但是我认为答案无法分析漏洞。请参阅:*((*(&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 ++语言是否允许取消引用。


我错过了类似的问题,但是这个问题有细微的不同。我已经了解了代码的工作原理,并且了解了将指针从数组的最后一个元素后移去通常存在问题。我要问的是,数组对象在表达式中使用时会衰减为指针的事实是否允许例外。我认为这可能是因为,取消引用指向对象的指针通常会导致对象值本身在表达式中使用(如果对象不存在,这将是一个问题)。

c c++ arrays pointers language-lawyer

7
推荐指数
1
解决办法
190
查看次数

C/C++故意超出范围索引

说我有一个像这样的数组:

int val[10];
Run Code Online (Sandbox Code Playgroud)

我故意用从负值到任何高于9的值来索引它,但没有以任何方式使用结果值.这可能是出于性能原因(也许在进行数组访问后检查输入索引会更有效).

我的问题是:

  1. 这样做是否安全,或者我是否会遇到某种内存保护障碍,有可能破坏某些指数的内存或类似情况?
  2. 如果我像这样访问超出范围的数据,它可能没有效率吗?(假设数组没有内置范围检查).
  3. 这会被认为是不好的做法吗?(假设写了一条注释,表示我们知道使用超出范围的索引).

c c++ arrays

6
推荐指数
3
解决办法
466
查看次数

如何初始化静态向量成员?

例如

struct A
{
    static vector<int> s;
};

vector<int> A::s = {1, 2, 3};
Run Code Online (Sandbox Code Playgroud)

但是,我的编译器不支持初始化列表.有什么办法可以轻松实现吗?lambda函数在这里有用吗?

c++ lambda static

6
推荐指数
1
解决办法
2万
查看次数

C++是否合法地使用超过数组末尾2或更多的地址?

一个过去的数组元素的地址通过下标:是否符合C++标准?

它似乎有具体采取的地址语言一个超过数组结束.

如果没有被解雇,为什么在结束时22,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++ arrays

6
推荐指数
1
解决办法
227
查看次数

什么是指针超过对象的末尾意味着什么?

在C++ Primer的第2章"变量和基本类型"中,它说:

指向对象的指针和指向不同对象末尾的指针可以保持相同的地址.

我不是母语人士,我认为这就是为什么我对句子"一个指针越过一个对象的结尾"感到有点困惑.有人会告诉我这意味着什么吗?

c++

5
推荐指数
2
解决办法
2014
查看次数

超过最后一个数组元素末尾的指针是否等于超过整个数组末尾的指针?

编译器在编译代码时出现分歧

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,为什么?

c++ arrays pointers language-lawyer

5
推荐指数
1
解决办法
143
查看次数

C++ 标准是否对获取数组索引表达式的地址提供任何保证?

具体来说,考虑以下代码:

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++ 中是否也存在&[]->+ …

c++ language-lawyer

5
推荐指数
0
解决办法
164
查看次数

标签 统计

c++ ×10

arrays ×4

language-lawyer ×3

pointers ×3

c ×2

boost ×1

c++11 ×1

cpu ×1

icc ×1

lambda ×1

optimization ×1

performance ×1

static ×1

std ×1

stl ×1