Crash on close

Here's my program. What it does is irrelevant. The problem is that it finishes all of its operations and then immediately crashes. Another problem is that it only crashes part of the time, performing the same static operations. There are no random numbers used or anything that would cause the operation to be so erratic.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
#include "BitSequence.cpp"
using namespace std;

int main(){

    unsigned int * array = static_cast<unsigned int*>(calloc(2, 4));
    *(array) = 42345234;
    *(array + 1) = 64;
    BitSequence * b = new BitSequence(array, 64, 0);
    BitSequence * c = (*b).getBits(10, 5);

    cout << "foo";
    
    delete c;   //Adding this delete line sometimes makes it work.
    delete b;   //This delete line doesnt change anything.

    return 0;
}


The printout from this code is always "foo", and then a crash occurs. The weird part is, the program crashes after printing, even if I get rid of lines 14 and 15.

But it gets weirder. If I put in the first line "delete c;", the program compiles. But only sometimes. I'd say that its a 50/50 chance of crashing. Adding the "delete b;" Changes nothing.

I'm attaching the relevant BitSequence code, but I doubt that it has anything to do with the problem, because the program always prints "foo".

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
#include "Integer.cpp"
#include <iostream>
class BitSequence{
private:
unsigned int length;
unsigned int * data;
public:
BitSequence(unsigned int * const array, unsigned int const &arrayLength, unsigned int const &offset){//Constructor
        length = arrayLength;
        data = static_cast<unsigned int*>(calloc(bitLengthToIntLength(arrayLength), 4));
        const unsigned int endArray = bitLengthToIntLength(arrayLength)-1;
        for(unsigned int i = 0; i < endArray; i++){
            *(data+i) = (*(array+i) << offset) | (*(array + i + 1) >> (32 - offset));
        }
        *(data+endArray+1) = *(array + endArray + 1) << offset;
    }
~BitSequence(){
        free(data);
    }

BitSequence * getBits(unsigned int const &start, unsigned int const &bitLength){
        return new BitSequence(data, 4, 3);
        //For the sake of testing, I just had this function return the same variables
    }

    private:
    /*Given a length value in bits, returns the number of ints needed to store the data.*/
    unsigned int bitLengthToIntLength(unsigned int const &numBits){
        return (numBits >> 5) + (numBits & 0x0000001F ? 1:0);
    }
}


My editor is CodeBlocks 8.02
Compiler is MinGW make 3.8.1
I'm running Windows 7 Home Premium 64-bit.

Please let me know if you have any ideas on what is going on.
Last edited on
Heap Corruption. Here:

1
2
3
4
5
6
        //  say, for example, bitLengthToIntLength returns 4
        data = static_cast<unsigned int*>(calloc(bitLengthToIntLength(arrayLength), 4));  // 4 members allocated
        const unsigned int endArray = bitLengthToIntLength(arrayLength)-1;  // endArray = 4-1 = 3
//...
        *(data+endArray+1) = *(array + endArray + 1) << offset;  // *(data+endArray+1) =
        //  data[endArray+1] = data[3 + 1] = data[4] = past the end of the buffer (data[3] is the last valid element) 



A few other unrelated notes:

-) Why on earth are you using calloc? mixing new and malloc family functions isn't really a good idea. Plus you don't even seem to be using the zero-memory feature of calloc anyway.

-) Why so afraid of [brackets]? The pointer math approach makes the code much harder to follow.

EDIT:

-) Why are you #including cpp files? You really shouldn't be. See this: http://cplusplus.com/forum/articles/10627/
Last edited on
I had a very long and courteous post typed out, but this website seems to log me out constantly, and so when I submitted it, it erased all of the data and wouldn't let me log in.

So long story short, thank you very much for your help. I realized my error, and will try to correct my irregular coding practices. Thank you especially for the resource on header files.

This is probably not something I would have discovered for a long time, and I really appreciate your help.

Edits:
Having said that, there are justifications for using malloc.
- Since it doesn't clear the allocated memory, it *can be* faster than new. Free *may* also faster than delete.
- The memory block can be resized with realloc.
Last edited on
This is probably not something I would have discovered for a long time, and I really appreciate your help.


No problem ^^. Glad I could help.

- Since it doesn't clear the allocated memory, it *can be* faster than new. Free *may* also faster than delete.


calloc is almost undoubtedly always slower than new for basic memory types because it zero's the memory after it's allocted (whereas new does not alter the memory after allocation).

You might be thinking of malloc, which just gives you an unaltered allocated buffer.

But I doubt there's any performance difference between new/delete and malloc/free for basic types.

- The memory block can be resized with realloc.


Then why not a vector?
Topic archived. No new replies allowed.