byte* 不会在库中保持“000000”

Posted

技术标签:

【中文标题】byte* 不会在库中保持“000000”【英文标题】:byte* does not stay "000000" in Library 【发布时间】:2014-08-26 10:52:48 【问题描述】:

我在我的 XCode 静态库(objective c++ with libc++)中有一个奇怪的行为:我有一个分配的 ByteArray(无符号字符 *),它没有从静态库中分配给 0(超过给定大小)。如果我直接在设计项目中构建源代码,一切正常,并且指针指向具有给定大小且所有字节设置为 0 的无符号字符数组。从静态库中,看起来数组被覆盖,因为某些字节在数组中设置了随机字节

我在 OSX (10.9.4) for ios (7.1) 上的 XCode (5.1.1) 中编译,使用 libc++ 作为 C++ 标准库,语言方言 -std=c++11 和默认编译器(Apple LLVM 5.1)。

我尝试了不同的分配方式:

typedef unsigned char byte;
class ByteArray 
private:
    byte* mBytes;
    long mSize;  

public:
    ByteArray(long Size)


        //1
        this->mBytes = new byte[Size]();

        //2
        this->mBytes = (byte*) calloc(Size, sizeof(byte));

        //3
        this->mBytes = (byte*)malloc(Size*sizeof(byte));
        memset(this->mBytes, 0, Size);

        //4
        this->mBytes = (byte*)malloc(Size*sizeof(byte));
        byte zero = 0;
        for (int i = 0; i < Size; i++)
        
            memcpy(this->mBytes + i, &zero, 1);
        

        //Set size
        this->mSize = Size;
    

    //with Data
    ByteArray(byte* Bytes, long Size)
       this->mBytes = new byte[Size]();
       memcpy(this->mBytes, Bytes, Size);
       this->mSize = Size;
    

我是这样初始化的:

ByteArray* zeroBytes = new ByteArray(16);

以上代码在 ByteArray 持有者类的类初始化器中: 从库中我得到类似(HEX)的结果: 000000b0b1c9555190be923b00000900

而不是: 000000000000000000000000000000000

有没有人已经陷入这种奇怪的行为并弄清楚是什么原因造成的?

编辑: 如果我用给定的数据初始化字节*永远不会损坏。

编辑2: 所以,我想通了,缓冲区溢出发生在另一个库中,这杀死了一切。非常感谢您的所有帮助。

【问题讨论】:

1) 添加有关操作系统和编译器的信息 2) 添加表现出意外行为的测试代码。 所有 1,2,3,4 都将所有字节设置为零。问题一定出在其他地方;例如,在不同的代码中可能存在缓冲区溢出,它会破坏您的数组。如果您发布 MCVE 会有所帮助 我初始化“空”数组,直接把它拿出来。没有功能,成员或任何接触过它的东西。我已经考虑过编译器从库中剥离一些东西,所以我在没有优化的情况下编译并且行为仍然出现。如果它是来自另一个线程的缓冲区溢出或其他什么,用数据初始化的 ByteArrays 也会损坏,但它们不是。 @MattMcNabb 我听从了您的建议并构建了一个最小的测试系统,它在那里工作得像一个魅力(两种方式,作为库和直接),所以你可能是对的。但是我如何找出问题发生在哪里?唯一改变的数组是“空”数组,填充数据的数组保持不变,我在将数组放入控制台日志之前对其进行初始化。 在你的测试系统中添加东西,直到你再次出现错误。如果你最终得到真正的代码,那么它必须在两者之间的某个阶段发生 【参考方案1】:

根据 cmets,问题似乎出在代码的其他地方。您可能要检查的一件事是查看是否在任何地方使用了字节打包(请参阅#pragma pack effect)

如果使用字节打包,请确保所有#pragma pack(push,1) 都具有匹配的#pragma pack(pop)。如果不是(即有一个悬空的#pragma pack(push,1)),那么根据给定源文件包含哪些头文件,您最终可能会在不同的源文件中得到具有不同大小的相同数据结构。

在弄清楚这一点之前,我花了几天时间研究一些遗留代码;如果这有帮助,那就太好了。如果它没有用,我很乐意从这篇文章中删除它。

【讨论】:

避免此类问题的一个好方法是不要使用pragma pack! 我会走好路的。对不起,蒂姆,我在代码中的任何地方都没有使用 pragma pack。【参考方案2】:

如果您想一步完成分配和零初始化,只有calloc()new T[n]() 可以。其他人在数组中留下未初始化的“垃圾”,当然有时可能恰好为零。请不要问为什么它在一个构建中是零而在另一个构建中是非零,​​它只是未定义,它可以是任何东西,包括圣经的开头或国家机密。

您也可以使用memset() 一次将所有字节归零。不要使用memcpy() 在循环中复制单个字节——这是一种巨大的悲观。

【讨论】:

new byte[Size]() 应该执行值初始化吗? 这些是我将所有内容设置为 0 的不同尝试,我知道 calloc(),这是我的第一次尝试。如果我直接在我的 App Project 中编译它,一切正常并且按预期(所有这些尝试),但是如果我将所有内容预编译为静态库并将该库链接到我的 App-Project 中,则会出现所描述的行为。我测试确定的其他选项。 @BryanChen:是的,您对new 的结尾是正确的()。我会更新这部分的答案。谢谢。

以上是关于byte* 不会在库中保持“000000”的主要内容,如果未能解决你的问题,请参考以下文章

java中如何让byte[]与string类型转换后,保持不变

在库中处理 Posix 信号

使用 CMake 在库中查找符号

在库中使用 React 路由器 - 无法使用 useHistory()

Angular Schematics:在库中运行单元测试时出错

在库中使用 fstream 时,可执行文件中出现链接器错误