相关疑难解决方法(0)

反序列化函数(字节数组到 uint32 )

编写反序列化函数将字节数组转换为 32 位无符号整数的最佳方法是什么?

    typedef unsigned long  uint32;

    uint32 deserialize_uint32(unsigned char *buffer)
    {
        uint32 value = 0;

        value |= buffer[0] << 24;
        value |= buffer[1] << 16;
        value |= buffer[2] << 8;
        value |= buffer[3];
        return value;

    }

    unsigned char* deserialize_uint32B(unsigned char *buffer, uint32* value)
    {
        *value = 0;

        *value |= buffer[0] << 24;
        *value |= buffer[1] << 16;
        *value |= buffer[2] << 8;
        *value |= buffer[3];
        return buffer + 4;
    }
Run Code Online (Sandbox Code Playgroud)

谢谢!或者如果有更好的方法请告诉我..谢谢!

c arrays deserialization

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

没有兼容的方式来转换相同大小的签名/无符号

我担心我可能会遗漏一些微不足道的东西,但是如果你想保留原始的无符号值,似乎没有实际的安全方式来转换为签名类型.

在reinterpret_cast上,5.2.10没有列出整数到整数的转换,因此没有定义(而static_cast定义没有额外的转换).关于积分转换4.7.3基本上说大型无符号的转换将是实现定义的(因此不可移植).

这似乎是有限的,因为我们知道,例如,uint64_t在任何硬件上,应该可以安全地转换为a int64_t和back而不会改变值.另外,标准布局类型的规则实际上保证了安全转换,如果我们memcpy在两种类型之间而不是分配.

我对么?有没有合理的理由为什么不能reinterpret_cast在整数类型之间有足够的大小?


澄清:肯定无符号的签名版本不保证值,但它只是我考虑的往返(unsigned => signed => unsigned)


更新:仔细查看答案并交叉检查标准,我相信memcpy实际上并没有保证工作,因为它没有说明这两种类型是布局兼容的,也不是char类型.进一步更新,深入研究C-standard这个memcpy应该可以工作,因为目标的大小足够大并且它复制了字节.


答案:似乎没有技术上的理由说明为什么不允许reinterpret_cast执行此转换.对于这些固定大小的整数类型,a memcpy保证可以工作,实际上只要中间可以表示所有的位模式,任何中间类型都可以使用(浮点数可能很危险,因为可能存在陷阱模式).通常,您不能在任何标准布局类型之间进行memcpy,它们必须是兼容的或char类型.这里的注明是特殊的,因为它们有额外的保证.

c++ language-lawyer c++11

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

打破严格的走样和生活来讲述它?

我试图在我在C++ 11中编写的同一个应用程序中使用两个库LIBSVMLIBLINEAR.LIBSVM和LIBLINEAR都在基本上是基于行的稀疏矩阵表示中输入它们:存在节点结构

struct svm_node
{
    int index;
    double value;
};
Run Code Online (Sandbox Code Playgroud)

稀疏矩阵本身就是struct svm_node **,每行都是a struct svm_node *,行终止index = -1.调用此结构的LIBLINEAR版本feature_node并具有相同的定义.虽然LIBSVM和LIBLINEAR由同一作者写的,svm.hlinear.h,因此struct svm_nodestruct feature_node是没有丝毫关系.

在某些情况下,我想创建一个内核SVM模型(仅由LIBSVM实现)和一个逻辑回归模型(仅由LIBLINEAR实现)我的数据.数据集传递给它们各自的库---在二进制级别上,相同的---稀疏矩阵表示,可能非常大,我宁愿避免memcpy()全部.一个简单的reinterpret_cast<feature_node **>(svm_node_ptr_ptr_variable)似乎做得很好.

我也在-flto发布版本中使用LLVM的完整程序优化(),因此我希望确保代码不会以不可预测的方式进行优化.

有什么办法型双关语svm_node **feature_node **避免可能的(当前或未来)编译器优化导致的任何破损?__attribute__((__may_alias__))在这里有帮助,如果有,我应该如何使用它?


如果__attribute__((__may_alias__))只对类型有意义,那么如果我创建了自己的struct和指向结构的指针,它是否有效

struct __attribute__((__may_alias__)) SparseElement {
    int index;
    double value;
};
typedef SparseRow SparseElement * __attribute__((__may_alias__));
Run Code Online (Sandbox Code Playgroud)

然后将retinterpret_casted 传递SparseRow * …

c++ strict-aliasing type-punning c++11

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

将C结构转换为具有较少元素的另一个结构是否安全?

我正在尝试在C上做OOP(只是为了好玩)而且我想出了一个方法来进行数据抽象,方法是使用公共部分和更大的结构,首先是公共部分,然后是私有部分.这样我在构造函数中创建整个结构并将其返回到小结构.这是正确的还是会失败?

这是一个例子:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

// PUBLIC PART (header)
typedef struct string_public {
    void (*print)( struct string_public * );
} *string;

string string_class_constructor( const char *s );
void string_class_destructor( string s );

struct {
    string (*new)( const char * );
    void (*delete)( string );
} string_class = { string_class_constructor, string_class_destructor };


// TEST PROGRAM ----------------------------------------------------------------
int main() {
    string s = string_class.new( "Hello" );
    s->print( s );
    string_class.delete( s ); s = NULL;
    return 0;
}
//------------------------------------------------------------------------------ …
Run Code Online (Sandbox Code Playgroud)

c struct type-punning

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

使用强制转换为"错误"类型的指针算法

我有一个结构数组,我有一个指向其中一个结构的成员的指针.我想知道数组的哪个元素包含该成员.这有两种方法:

#include <array>
#include <string>

struct xyz
{
    float x, y;
    std::string name;
};

typedef std::array<xyz, 3> triangle;

// return which vertex the given coordinate is part of
int vertex_a(const triangle& tri, const float* coord)
{
    return reinterpret_cast<const xyz*>(coord) - tri.data();
}

int vertex_b(const triangle& tri, const float* coord)
{
    std::ptrdiff_t offset = reinterpret_cast<const char*>(coord) - reinterpret_cast<const char*>(tri.data());
    return offset / sizeof(xyz);
}
Run Code Online (Sandbox Code Playgroud)

这是一个测试驱动程序:

#include <iostream>

int main()
{
    triangle tri{{{12.3, 45.6}, {7.89, 0.12}, {34.5, 6.78}}};
    for (const …
Run Code Online (Sandbox Code Playgroud)

c++ pointer-arithmetic undefined-behavior language-lawyer

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

严格别名规则和glibc的strlen实现

我已经阅读了一段时间的严格别名规则,我开始变得非常困惑.首先,我已经阅读了这些问题和一些答案:

根据它们(据我所知),char使用指向另一种类型的指针访问缓冲区违反了严格的别名规则.但是,glibc实现strlen()有这样的代码(删除了注释和64位实现):

size_t strlen(const char *str)
{
    const char *char_ptr;
    const unsigned long int *longword_ptr;
    unsigned long int longword, magic_bits, himagic, lomagic;

    for (char_ptr = str; ((unsigned long int) char_ptr 
             & (sizeof (longword) - 1)) != 0; ++char_ptr)
       if (*char_ptr == '\0')
           return char_ptr - str;

    longword_ptr = (unsigned long int *) char_ptr;

    himagic = 0x80808080L;
    lomagic = 0x01010101L;

    for (;;)
    { 
        longword = *longword_ptr++;

        if (((longword - lomagic) & himagic) …
Run Code Online (Sandbox Code Playgroud)

c glibc strict-aliasing

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

指针具有相同的内存地址,具有不同的值

我将内存地址从double转换为整数.即使他们指向相同的地址,为什么值不同?

#include<iostream>
using namespace std;

int main()
{
    double d = 2.5;
    auto p = (int*)&d;
    auto q = &d;
    cout<<p<<endl; // prints memory address 0x7fff5fbff660
    cout<<q<<endl; // print memory address  0x7fff5fbff660
    cout<<*p<<endl; //prints 0
    cout<<*q<<endl; // prints 2.5
    return 0;

}
Run Code Online (Sandbox Code Playgroud)

但为什么价值不同

0x7fff5fbff660
0x7fff5fbff660
0
2.5
Program ended with exit code: 0
Run Code Online (Sandbox Code Playgroud)

c++

7
推荐指数
3
解决办法
1220
查看次数

C,Unix域套接字,辅助数据和GCC; 使用CMSG_DATA宏

我怎样才能做到这一点:

*(int *)CMSG_DATA(hdr) = fd2pass;
Run Code Online (Sandbox Code Playgroud)

没有GCC提出这个:

error: dereferencing type-punned pointer will break strict-aliasing rules
Run Code Online (Sandbox Code Playgroud)

以与这些选项兼容的方式:

-Wall -Werror -pedantic
Run Code Online (Sandbox Code Playgroud)

c unix sockets gcc

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

没有联合的结构类型别名/标记联合

对于两个(或更多)structS:BaseSub具有共同第一(未命名)struct,是安全的转换/从投BaseSub反之亦然?

struct Base{
    struct{
        int id;
        // ...
    };
    char data[]; // necessary?
}

struct Sub{
    struct{
        int id;
        // same '...'
    };
    // actual data
};
Run Code Online (Sandbox Code Playgroud)

这些功能是否保证安全且技术上正确?(另外:零长度char data[]成员是否必要且有用?)

struct Base * subToBase(struct Sub * s){
    return (struct Base*)s;
}

struct Sub * baseToSub(struct Base * b){
    if(b->id != SUB_ID){
        return NULL;
    }

    return (struct Sub*)b;
}
Run Code Online (Sandbox Code Playgroud)

编辑

我没有计划Base在内部进一步嵌套Sub,而是可以在以后添加其他子类型(直接在下面Base),而无需更改Base …

c language-lawyer c11

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

将双精度数组转换为仅具有双成员而不复制数据的结构数组

我正在使用第三方C++库在Julia中做一些繁重的工作.在Julia方面,数据存储在类型的对象中Array{Float64, 2}(这大致类似于2D数组的双精度数).我可以使用指向a的指针将它传递给C++ double.但是,在C++方面,数据存储在一个名为的结构中vector3:

typedef struct _vector3
{
    double x, y, z;
} vector3;
Run Code Online (Sandbox Code Playgroud)

我快速而肮脏的方法分为五个步骤:

  1. 在C++端动态分配结构数组
  2. 将输入数据复制double*vector3*
  3. 做重物
  4. 将输出数据复制vector3*double*
  5. 删除动态分配的数组

复制大量数据效率非常低.我可以使用一些神秘的技巧来避免复制数据doublestruct后面吗?我想以某种方式解释一个1D数组double(大小是3的倍数)作为具有3个double成员的结构的一维数组.

c++ struct casting julia

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