1

I got a strange behavior in my XCode static library (objective c++ with libc++): i have an allocated ByteArray (unsigned char *) and it does not allocate to 0 (over the given size) from within the static library. If i directly build the source in the Design Project everything works fine and the pointer points to an unsigned char array with the given size and all bytes set to 0. From within the static library, it looks like the array gets overwritten, because some bytes in the array have random bytes set

I'm compiling in XCode (5.1.1) on OSX (10.9.4) for iOS (7.1), using libc++ as C++ Standard Library with language Dialect -std=c++11 with the Default Compiler (Apple LLVM 5.1).

I tried allocating in different ways:

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;
    }
}

I'm initializing like this:

ByteArray* zeroBytes = new ByteArray(16);

The above Code is in the Class Initializer for an ByteArray holder Class: From within the library i get results like (HEX): 000000b0b1c9555190be923b00000900

instead of: 00000000000000000000000000000000

Does anyone already got into this strange behavior and has figured out what caused this?

edit: If i initialize with given data the byte* is never corrupt.

edit2: So, i figured it out, the Buffer owerflow happened in another Library and this killed everything. Thanks a lot for all of your help.

Da Maex
  • 481
  • 7
  • 27
  • 2
    1) add information about operating system and compiler 2) add the test code which exhibit the unexpected behavior. – pqnet Aug 26 '14 at 11:07
  • 2
    All of your 1,2,3,4 set all the bytes to zero. The problem must be elsewhere; for example maybe there is a buffer overflow in different code that splats your array. It would help if you post a [MCVE](http://stackoverflow.com/help/mcve) – M.M Aug 26 '14 at 11:32
  • I initialize the "empty" array and directly put it out. No Function, Member or whatever is ever touching it. I already thought about the Compiler stripping something out of the library, so i compiled without optimization and the behavior still appears. If it would be buffer overflow from another thread or whatever, ByteArrays initialized with data would be corrupt too, but they aren't. – Da Maex Aug 26 '14 at 11:42
  • @MattMcNabb i followed your advise and builded a minimal TestSystem, there it worked like a charme (both ways, as library and direct), so you are probably right. But how do i figure out where the problem occurs? The only Array who get changed is the "empty" one, data filled ones stay untouched and i initialize the Array right before putting it to console log. – Da Maex Aug 26 '14 at 12:33
  • 1
    add in stuff to your TestSystem until you get the bug reoccurring.. if you end up with the real code then it must happen at some stage in between – M.M Aug 26 '14 at 12:35
  • I think i found the Problem. In the main project another Library used this ByteArray and had a buffer owerflow at some Point! Thank you @MattMcNabb! You have no idea at which point of throwing the mac out of the window i was (writting from the second one ^^)! Well, Problem solved. – Da Maex Aug 27 '14 at 11:26

2 Answers2

1

Based on the comments it appears the problem is somewhere else in the code. One thing you may want to check for is to see if byte packing is used anywhere (see #pragma pack effect)

If byte packing is used make sure that all #pragma pack(push,1) have a matching #pragma pack(pop). If not (i.e. there is a dangling #pragma pack(push,1)) then, depending on which header files are included for a given source file, you could end up with the same data structure having a different size in different source files.

I spent days on some legacy code before figuring this out; if this helps, great. If it is not useful I'll gladly remove it from this post.

Community
  • 1
  • 1
Tim
  • 153
  • 1
  • 7
-3

If you want to allocate and zero-initialize in one step, only calloc() or new T[n]() will do. The others leave uninitialized "garbage" in the array, which of course may happen to be zero sometimes. Please don't ask why it's zero in one build and non-zero in another, it's just undefined, it could be anything, including the beginning of the bible or a state secret.

You can also use memset() to zero all the bytes at once. Don't use memcpy() to copy single bytes in a loop--that's a massive pessimization.

John Zwinck
  • 239,568
  • 38
  • 324
  • 436
  • `new byte[Size]()` should perform value initialization? – Bryan Chen Aug 26 '14 at 11:32
  • These are my different trys of setting everything to 0, i know about `calloc()` and it was my first attempt. If i compile it directly in my App Project everything works fine and as expected (with all those attempts), but if i precompile everything as a static library and link this library in my App-Project the described behavior appears. The other options i tested to be sure about. – Da Maex Aug 26 '14 at 11:34
  • 1
    @BryanChen: yes you're right about `new` with the trailing `()`. I'll update my answer for that part. Thanks. – John Zwinck Aug 26 '14 at 11:48