# c++ new throws exception, no idea why

This topic is 4131 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Hi, i am having a problem with new. I am calling 'new' many times a second and at some point it throws an exception. I got no idea why. I call: char *_type=new char[l+1]; The value of l is 4 or something like that. And the exception is thrown in __sbh_alloc_block(int):
    //  change size of free entry (front and back)
if (sizeNewFree != 0)
{
pEntry->sizeFront = sizeNewFree;
((PENTRYEND)((char *)pEntry + sizeNewFree -
-->                 sizeof(ENTRYEND)))->sizeBack = sizeNewFree;
}

The value of sizeNewFree is 20367508, memory usage looks fine in task manager (so no giant memory leaks) and i 'delete' all i 'new' when i don't need it any more. So i guess it's not free memory that's the problem. I tried catching the exception but when it's thrown once it keeps getting throwed so that didn't fix anything. Two things that might matter: I am using MSVC++ 6.0. I use multiple threads that all use new and delete extensively. Any help would be great! If you need any more info please ask.

##### Share on other sites
What is the thrown exception?

##### Share on other sites
What exception is thrown? And what's the contents of .what()?

Quote:
 I am calling 'new' many times a second and at some point it throws an exception.

How many times? Are we talking 100s or millions?

Quote:
 i 'delete' all i 'new' when i don't need it any more.

Is there some point where you call new many times before deleting, if so, then how many times approximatly.

Quote:
 I am using MSVC++ 6.0.I use multiple threads that all use new and delete extensively.

I don't have access to MSVC++ 6.0 myself, so I can't check this, but are you sure new is thread-safe? If new have any static variables, and no locks, then there is a good chance you are experiencing a race condition.

##### Share on other sites
I don't know what the thrown exception is, any idea how i can find that out using the debugger or using catch(...)?
edit: It's an Access Violation exception:
First-chance exception in server.exe: 0xC0000005: Access Violation.

Quote:
 Original post by CTarWhat exception is thrown? And what's the contents of .what()?

Isn't .what() just for Java? If not, how can i use it when i use catch(...)?

Quote:
 How many times? Are we talking 100s or millions?

Hundreds.

Quote:
 Is there some point where you call new many times before deleting, if so, then how many times approximatly.

No, maybe 3 threads at the same time calling new 3 or 4 times before deleting it again.

Quote:
 I don't have access to MSVC++ 6.0 myself, so I can't check this, but are you sure new is thread-safe?

I assumed it is (many programs these days use multiple threads) but i am starting to doubt it.

##### Share on other sites
The most likely cause is that you've got heap corruption somewhere in your program that causes bad things to happen when the small block handler goes to allocate a new block.

##### Share on other sites
Quote:
 Original post by Tree PenguinIsn't .what() just for Java? If not, how can i use it when i use catch(...)?

No, every class inherited from std::exception should have a .what() member.

Quote:
 I assumed it is (many programs these days use multiple threads) but i am starting to doubt it.

Yes many programs these days use threads, but not many programs at the time of VC6 used threads. That program is older than the first C++ standard (1998, the second was published in 2003 and we now have technical revisions). This could very well be the source of your problem.

##### Share on other sites
Quote:
 Original post by Tree PenguinI don't know what the thrown exception is, any idea how i can find that out using the debugger or using catch(...)?edit: It's an Access Violation exception:First-chance exception in server.exe: 0xC0000005: Access Violation.

It's worth noting that this is not a C++ exception. Access Violations, like Division by Zero, fall under the category of SEH exceptions, and are not part of the C++ standard and thus not portable to rely on being able to handle. As far as I know, one usually has to take special steps (involving compiling a specially patched version of your compiler) to handle these on OS X/Linux. It's far easier to treat them as bugs, since they represent avoidable error conditions, and 99% of the time, indicate you're doing stuff that surely wasn't what you'd intended.

(SuperPig's Introduction to Debugging is a good starting point for this kind of thing)

Quote:
Quote:
 I don't have access to MSVC++ 6.0 myself, so I can't check this, but are you sure new is thread-safe?

I assumed it is (many programs these days use multiple threads) but i am starting to doubt it.

As has been already mentioned, VS6 is positively ancient. In this train of thought, Visual Studio 2005 Express is available for free from Microsoft, and is far less ancient. I highly recommend trying it out (just make sure you follow the instructions carefully, there's post-installer installation steps that need to be followed).

##### Share on other sites
It turns out to be the multiple threads problem.
For now i fixed it by using new only at places where it's really neccessery and i use a 'notbusynewing' flag, looping the threads that want to use new until it's true, which signales the first thread that sees it is the next one in line.

It's one of the ugliest things i've done in a long time but it's an emergency fix and it works.

##### Share on other sites
There are thread safe new instances out there. Also, seriously upgrade to the FREE .NET 2005. VC6 is buggy and non-complaint, it will bite you in the butt, sooner rather then later.

##### Share on other sites
Quote:
 Original post by Anonymous PosterThere are thread safe new instances out there. Also, seriously upgrade to the FREE .NET 2005.

I know, got no time to switch right now.

Quote:
 VC6 is buggy and non-complaint, it will bite you in the butt, sooner rather then later.

I have used it for a few years now and the only real problem i faced is the problem i just discussed.

##### Share on other sites
Quote:
 Original post by Tree PenguinIt turns out to be the multiple threads problem.For now i fixed it by using new only at places where it's really neccessery and i use a 'notbusynewing' flag, looping the threads that want to use new until it's true, which signales the first thread that sees it is the next one in line.It's one of the ugliest things i've done in a long time but it's an emergency fix and it works.
If what you've done looks something like this:
if (notbusynewing){    notbusynewing = false;    myPtrVar = new int[1000]; // or whatever    notbusynewing = true;}
Then you have just shifted problem. Consider what happens when you switch threads after the code goes into the 'if' statement group, but has not yet reached that 'notbusynewing = false;' line. Another thread can then do the same thing.
For some ideas of how to get aroung this: Clicky

##### Share on other sites
Quote:
 Original post by Tree PenguinI don't know what the thrown exception is, any idea how i can find that out using the debugger or using catch(...)?edit: It's an Access Violation exception:First-chance exception in server.exe: 0xC0000005: Access Violation.

That's not an exception in the sense that we usually mean. That is, it isn't one that you could try/catch.

Quote:
Quote:
 Original post by CTarWhat exception is thrown? And what's the contents of .what()?

Isn't .what() just for Java? If not, how can i use it when i use catch(...)?

Not only is .what() not just for Java, it's *not* for Java. :)

If it *were* an exception that could be thrown, you would catch it like this:

try {  // stuff} catch (std::runtime_error& ex) {  std::cout << ex.what() << std::endl;}

It's usual in C++ to catch exception objects by reference, unless you're using a library that expects you to do otherwise.

If your problem were an exception of this sort, then the exception thrown by new would be of type 'std::bad_alloc', which is derived from std::runtime_error. If I'm remembering correctly, anyway (which I'm probably not).

However, your error happens because of some kind of corruption of the data that's doing book-keeping on memory. It's likely that you overwrote the bounds of one of those char arrays that you are allocating manually.

By the way, manual allocation is frequently uncalled for in C++. And allocting arrays of *chars* makes me suspicious that you might be trying to use them for string data, which would make me really sad.

Quote:
Quote:
 Is there some point where you call new many times before deleting, if so, then how many times approximatly.

No, maybe 3 threads at the same time calling new 3 or 4 times before deleting it again.

That smells a *lot* like one thread tries to write to an array, expecting it to have been already resized by another thread, but getting to it before the resize happened (race condition).

##### Share on other sites
Quote:
 Original post by iMalcIf what you've done looks something like this:if (notbusynewing){ notbusynewing = false; myPtrVar = new int[1000]; // or whatever notbusynewing = true;}Then you have just shifted problem. Consider what happens when you switch threads after the code goes into the 'if' statement group, but has not yet reached that 'notbusynewing = false;' line. Another thread can then do the same thing.

I learned at college that compilers use a cpu instruction that checks and sets a boolean in one cpu cycle with code like this, and so far that indeed seems to be the case as i did not have the problem since i used that code (even with many threads).

I'll look at the link you gave me anyway, thanks.

@Zahlman:

About the 0xC0000005 exception, i thought that all exceptions existed to be thrown when an error occurs and catched by the program so the program can continue like normal (as in java afaik). Didn't know that it was different for exceptions like this.

Quote:
 However, your error happens because of some kind of corruption of the data that's doing book-keeping on memory.

That is probably the case, if it's my arrays that have their boundaries overwritten it's because the memory for it wasn't allocated at all (because of the multiple thread problem), it's either that or it's the book-keeping data itself that gets corrupted. As i already said it works fine as long only one thread uses new, so i can't think of any other explanation.

About the char array: no, it's not a string, it contains bytes of binary data. I should probably use (unsigned) __int8 or BYTE (which also is (unsigned) char) instead to make that clear.

Quote:
 By the way, manual allocation is frequently uncalled for in C++.

Why is that? Anyway, i only use new when i need an array or object that can be passed on through out the program.

##### Share on other sites
Quote:
 Original post by Tree PenguinI learned at college that compilers use a cpu instruction that checks and sets a boolean in one cpu cycle with code like this, and so far that indeed seems to be the case as i did not have the problem since i used that code (even with many threads).

While you can test and set a value atomically (though not in one instruction to my knowledge) I think it's unlikely your compiler produces code like this by default. I would use a mutex - this is after all why they exist.

Quote:
 Original post by Tree PenguinWhy is that? Anyway, i only use new when i need an array or object that can be passed on through out the program.

Because manual allocation is subject to bugs time consuming to write and as you have discovered not necessarily thread safe. The C++ standard library provides std::vector which provides an array that takes care of all that for you

##### Share on other sites
Quote:
 Original post by chowe6685While you can test and set a value atomically (though not in one instruction to my knowledge) I think it's unlikely your compiler produces code like this by default.

Yes, in one CPU instruction (there are several that are suitable on the x86). That's why it can be atomic. [smile]

##### Share on other sites
I've always implemented a test and set using something like

mov eax, 0x1xchg eax, memoryaddresstest eax

of these only xchg is guaranteed to be atomic and it's only a part of the test and set operation

Is there a better way?

##### Share on other sites
Well, there's BTS (Bit Test And Set) or, on Pentiums, XCHGCMP and XCHGCMP8B. Don't ask me what's best though.

##### Share on other sites

This topic is 4131 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account

Register a new account

• ### Forum Statistics

• Total Topics
628644
• Total Posts
2984007

• 9
• 9
• 10
• 21
• 20