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类型转换后,保持不变
在库中使用 React 路由器 - 无法使用 useHistory()