相关疑难解决方法(0)

508
推荐指数
8
解决办法
5万
查看次数

调整std :: vector <std :: unique_ptr <T >>的大小

一般概念似乎与正确使用的拥有原始指针相比没有时间开销,只要std::unique_ptr足够的优化.

但是std::unique_ptr,特别是在复合数据结构中使用std::vector<std::unique_ptr<T>>呢?例如,调整矢量的基础数据的大小,这可能发生在push_back.各地要隔离性能,我环路pop_back,shrink_to_fit,emplace_back:

#include <chrono>
#include <vector>
#include <memory>
#include <iostream>

constexpr size_t size = 1000000;
constexpr size_t repeat = 1000;
using my_clock = std::chrono::high_resolution_clock;

template<class T>
auto test(std::vector<T>& v) {
    v.reserve(size);
    for (size_t i = 0; i < size; i++) {
        v.emplace_back(new int());
    }
    auto t0 = my_clock::now();
    for (int i = 0; i < repeat; i++) {
        auto back = std::move(v.back()); …
Run Code Online (Sandbox Code Playgroud)

c++ vector compiler-optimization unique-ptr c++11

33
推荐指数
2
解决办法
2290
查看次数

用memcpy"构造"一个​​可复制的对象

在C++中,这段代码是否正确?

#include <cstdlib>
#include <cstring>

struct T   // trivially copyable type
{
    int x, y;
};

int main()
{
    void *buf = std::malloc( sizeof(T) );
    if ( !buf ) return 0;

    T a{};
    std::memcpy(buf, &a, sizeof a);
    T *b = static_cast<T *>(buf);

    b->x = b->y;

    free(buf);
}
Run Code Online (Sandbox Code Playgroud)

换句话说,是*b一个生命已经开始的对象?(如果是的话,它什么时候开始呢?)

c++ lifetime language-lawyer

11
推荐指数
2
解决办法
1377
查看次数

我可以使用memcpy写入多个相邻的标准布局子对象吗?

免责声明:这是试图深入研究一个更大的问题,所以请不要挂断该示例在实践中是否有任何意义.

并且,是的,如果要复制对象,请使用/提供复制构造函数.(但请注意,即使该示例也不会复制整个对象;它会尝试在几个相邻(Q.2)整数上显示一些内存.)


给定C++ 标准布局 struct,我可以使用一次memcpy写入多个(相邻)子对象吗?

完整示例:(https://ideone.com/1lP2Gd https://ideone.com/YXspBk)

#include <vector>
#include <iostream>
#include <assert.h>
#include <inttypes.h>
#include <stddef.h>
#include <memory.h>

struct MyStandardLayout {
    char mem_a;
    int16_t num_1;
    int32_t num_2;
    int64_t num_3;
    char mem_z;

    MyStandardLayout()
    : mem_a('a')
    , num_1(1 + (1 << 14))
    , num_2(1 + (1 << 30))
    , num_3(1LL + (1LL << 62))
    , mem_z('z')
    { }

    void print() const {
        std::cout << 
            "MySL Obj: " <<
            mem_a << " / " …
Run Code Online (Sandbox Code Playgroud)

c++ memcpy language-lawyer

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

ARM Neon:如何将uint8x16_t转换为uint8x8x2_t?

我最近发现了vreinterpret {q} _dsttype_srctype转换运算符.但是,这似乎不支持此链接(页面底部)中描述的数据类型的转换:

一些内在函数使用以下形式的向量类型数组:

<type><size>x<number of lanes>x<length of array>_t

这些类型被视为包含名为val的单个元素的普通C结构.

示例结构定义是:

struct int16x4x2_t    
{
    int16x4_t val[2];     
};
Run Code Online (Sandbox Code Playgroud)

你知道如何转换uint8x16_tuint8x8x2_t

请注意,使用union无法可靠地解决问题(从非活动成员读取导致未定义的行为编辑:这只是C++的情况,而事实证明C允许类型惩罚),也没有使用指针来强制转换(打破严格别名规则).

c c++ arm vectorization neon

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

"C++编程语言第4版"第19.3.3.1节中的代码是否有效?

第19.3节呈现了一章,其主要重点是运算符重载的字符串表示,特别是特种作业[],->().它实现了copy_from()如下的辅助功能:

void String::copy_from(const String &x)
    // make *this a copy of x
{
    if (x.sz <= short_max)
    {
        memcpy(this, &x, sizeof(x);
        ptr = ch;
    }
    else
    {
        ptr = expand(x.ptr, x.sz+1);
        sz = x.sz;
        space = 0;
    }
}
Run Code Online (Sandbox Code Playgroud)

类接口如下所示:

#ifndef STRING_EXERCISE_H
#define STRING_EXERCISE_H

namespace simple_string
{
    class String;
    char *expand(const char *ptr, int n);
}

class String
{
    public:
        String(); // default constructor x{""}
        explicit String(const char *p); // constructor from …
Run Code Online (Sandbox Code Playgroud)

c++

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

使用 memcpy 和 memset 重新分配数组

我接管了一些代码,并遇到了一个奇怪的数组重新分配。这是一个 Array 类中的函数(由 JsonValue 使用)

void reserve( uint32_t newCapacity ) {
    if ( newCapacity > length + additionalCapacity ) {
        newCapacity = std::min( newCapacity, length + std::numeric_limits<decltype( additionalCapacity )>::max() );
        JsonValue *newPtr = new JsonValue[newCapacity];

        if ( length > 0 ) {
            memcpy( newPtr, values, length * sizeof( JsonValue ) );
            memset( values, 0, length * sizeof( JsonValue ) );
        }

        delete[] values;

        values = newPtr;
        additionalCapacity = uint16_t( newCapacity - length );
    }
}
Run Code Online (Sandbox Code Playgroud)

我明白这一点;它只是分配一个新数组,并将旧数组中的内存内容复制到新数组中,然后将旧数组的内容清零。我也知道这样做是为了防止调用析构函数和移动。

JsonValue是一个带有函数的类,以及一些存储在联合中的数据(字符串、数组、数字等)。

我担心的是这是否实际上是定义的行为。我知道它有效,并且自从我们几个月前开始使用它以来一直没有问题;但如果它未定义,那么并不意味着它会继续工作。 …

c++ memory-reallocation

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

可以memcpy为std :: aligned_storage吗?

std :: aligned_storage :: type是POD类型.POD类型可以memcpy.但是,如果将新的非平凡可复制类型放置到std :: aligned_storage会发生什么?它能记得那个std :: aligned_storage吗?

非平凡可复制类型(非POD类型)不能memcpy,行为未定义.如果std :: aligned_storage memcpy是非平凡可复制的类型,它是否也是未定义的行为?

#include <new>
#include <type_traits>
#include <cstring>
#include <iostream>

struct y { int a; } ;

// non-trivially-copyable
struct t
{
    y a;
    int* p;
    t(){ p = new int{ 300 }; }
    t( t const& ){ a.a += 100; }
    ~t(){ delete p; }
};

int main()
{   // Block 1
    { 
        t a; a.a.a = 100;
        t b; b.a.a = 200;
        // std::memcpy(&b,&a,sizeof(t));  // abort...non-trivially-copyable
    } …
Run Code Online (Sandbox Code Playgroud)

c++ memcpy object-lifetime c++14

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

为什么 std::memcpy (作为类型双关的替代方法)不会导致未定义的行为?

sizeof(double) char在寻找将s 组合到 a 的方法时double,我读了几篇文章,std::memcpy推荐使用以下方法:

char bytes[sizeof(double)];
// fill array
double d;
std::memcpy(&d, bytes, sizeof(double));
Run Code Online (Sandbox Code Playgroud)

但是,我想知道为什么进一步使用d可以定义行为。

如果它不是一个double,而是一个复杂的类对象,那么访问它肯定也不会被定义,不是吗?那么,为什么double.

编辑:为了使我的问题清楚,我想指定我的目标:我想找到一种方法将多个chars 组合成 adouble并进一步使用这个 double,而不会导致未定义的行为。我double希望指定 的值。无论如何,我认为这是不可能的,因为标准甚至没有说明任何有关大小的信息,更不用说double. 但是,我要求d一些有效的(即“可访问的”)double值。

c++ undefined-behavior language-lawyer

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

将std :: memcpy用于非平凡可复制类型的对象

标准定义我们可以通过以下方式使用std :: memcpy:

对于任何简单的可复制类型T,如果指向T的两个指针指向不同的T对象obj1和obj2,其中obj1和obj2都不是基类子对象,如果构成obj1的基础字节(1.7)被复制到obj2中,obj2将随后保持与obj1相同的值.

如果我们将该函数应用于非平凡可复制类型的对象,我们可能会遇到什么样的潜在问题?以下代码的工作原理就好像它适用于普通可复制类型:

#include <iostream>
#include <cstring>

using std::cout;
using std::endl;

struct X
{
    int a = 6;
    X(){ }
    X(const X&)
    {
        cout << "X()" << endl;
    }
};

X a;
X b;
int main()
{
    a.a = 10;
    std::memcpy(&b, &a, sizeof(X));
    cout << b.a << endl; //10
}
Run Code Online (Sandbox Code Playgroud)

DEMO

c++ types

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

暧昧的遗产

我正在努力提供一组需要结构感知的序列化方法.因此,我构建了一个类模板,为从中继承的所有类提供这些方法.

这就是我现在所拥有的:

template<typename T>
class serializable
{
    protected:
        serializable() = default;
    public:
        size_t size_of() { return sizeof(T); }
        void   dump(void* data) { std::memcpy(data, this, serializable<T>::size_of()); }
        void   load(void* data) { std::memcpy(this, data, serializable<T>::size_of()); }
        virtual void serialize()
        {
            std::cout << "Default serialize : size " << serializable<T>::size_of() << std::endl;
        }
};

struct point : public serializable<point>
{
    float p[3];
};
struct particle : public point, public serializable<particle>
{
    float v[3];
};

int main()
{
    particle p;
    p.serialize();

    return 0;
} …
Run Code Online (Sandbox Code Playgroud)

c++ inheritance templates

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

std :: is_trivially_copyable要求

c ++标准(和几个SO 答案)声明要符合条件is_trivially_copyable<T>,类型T必须具有:

  1. 默认的析构函数,
  2. 没有虚拟功能,
  3. 没有虚拟基类.

(这些不是唯一的要求,但问题仅针对这些问题)

有人可以解释为什么?我没有看到违反这3个中的任何一个如何使得Tmemcpy不安全.

c++ type-traits c++11

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