Debug Assertion Failed! Expression: _Acrt_First_Block == Header

Debug Assertion Failed! Expression: __acrt_first_block == header

As this is a DLL, the problem might lie in different heaps used for allocation and deallocation (try to build the library statically and check if that will work).

The problem is, that DLLs and templates do not agree together very well. In general, depending on the linkage of the MSVC runtime, it might be problem if the memory is allocated in the executable and deallocated in the DLL and vice versa (because they might have different heaps). And that can happen with templates very easily, for example: you push_back() to the vector inside the removeWhiteSpaces() in the DLL, so the vector memory is allocated inside the DLL. Then you use the output vector in the executable and once it gets out of scope, it is deallocated, but inside the executable whose heap doesn't know anything about the heap it has been allocated from. Bang, you're dead.

This can be worked-around if both DLL and the executable use the same heap. To ensure this, both the DLL and the executable must use the dynamic MSVC runtime - so make sure, that both link to the runtime dynamically, not statically. In particular, the exe should be compiled and linked with /MD[d] and the library with /LD[d] or /MD[d] as well, neither one with /MT[d]. Note that afterwards the computer which will be running the app will need the MSVC runtime library to run (for example, by installing "Visual C++ Redistributable" for the particular MSVC version).

You could get that work even with /MT, but that is more difficult - you would need to provide some interface which will allow the objects allocated in the DLL to be deallocated there as well. For example something like:

__declspec(dllexport) void deallocVector(std::vector<std::string> &x);

void deallocVector(std::vector<std::string> &x) {
std::vector<std::string> tmp;
v.swap(tmp);
}

(however this does not work very well in all cases, as this needs to be called explicitly so it will not be called e.g. in case of exception - to solve this properly, you would need to provide some interface from the DLL, which will cover the vector under the hood and will take care about the proper RAII)


EDIT: the final solution was actually was to have all of the projects (the exe, dll and the entire googleTest project) built in Multi-threaded Debug DLL (/MDd)
(the GoogleTest projects are built in Multi-threaded debug(/MTd) by default)

Debug Assertion Failed Expression __acrt_first_block == header

For anyone else who runs into a similar problem, here is how I fixed it.

Essentially the function signature for the Init() function was the problem. The std::string parameter was causing the debug assertion to fire, my best guess as of right now was because of move semantics but that part I am still not sure on. So there are a couple of ways that I found to fix this.

Method 1:

Make the parameter a const char*. I don't quite like this approach as it then relies on C style strings and if you are trying to write a program in modern C++, this is a huge step backwards.

Method 2:

Make the parameter a const std::string&. Making it a const reference to a string prevents the move semantics (again as far as I know) and the assertion no longer fires. I prefer this fix as it keeps the program in modern C++.

I hope this helps anyone who has similar issues, and be careful with statics and move semantics.

Debug Assertion Failed! Expression: _pFirstBlock == pHead

In this case, the problem is that I was passing a std::string back across a .dll boundary.

Runtime Library config

  • If the MSVC Runtime library is set to Multi-threaded Debug DLL (/MDd), then this is no problem (it works fine).

  • If the MSVC Runtime library is set to Multi-threaded Debug (/MTd), then it will throw this error, which can be fixed with the following instructions.

Memory allocated in Memory Manager A and freed in Memory Manager B ...

The problem is that memory is allocated on the .dll side, then that same memory is freed on the application side. This means that memory manager A is allocating memory, and memory manager B is releasing that same memory, which generates errors.

The solution is to make sure that all memory passed back is not allocated in the DLL. In other words, the memory is always allocated on the application side, and freed on the application side.

Of course, the DLL can allocate/free memory internally - but it can't allocate memory that is later freed by the application.

Examples

This will not work:

// Memory is allocated on the .dll side, and freed on the app side, which throws error.
DLL std::string GetString();

This will work:

// Memory is allocated/freed on the application side, and never allocated in the .dll.
DLL int GetString(std::string& text);

However, this is not quite enough.

On the application side, the string has to be pre-allocated:

std::string text("");
text.reserve(1024); // Reserves 1024 bytes in the string "text".

On the .dll side, the text must be copied into the original buffer (rather than overwritten with memory that is allocated on the .dll side):

text.assign("hello");

Sometimes, C++ will insist on allocating memory anyway. Double check that the pre-allocation is still the same as it was:

if (text.capacity < 1024)
{
cout << "Memory was allocated on the .dll side. This will eventually throw an error.";
}

Another way that works is to use std::shared_ptr<std::string>, so even though memory is allocated in the .dll, it is released by the .dll (rather than the application side).

Yet another way is to accept a char * and a length which indicates the amount of pre-allocated memory. If the text that we want to pass back is longer than the length of pre-allocated memory, return an error.

Debug Assertion Failed OpenCv is_block_type_valid(header-_block_use)

Are you absolutely sure that the image has been loaded correctly?

I would think that it hasn't been loaded correctly and because of that the vector rgb is empty and, in turn, the element rgb[0] doesn't exist which triggers the exception ...

A couple of things I noted:

  1. Use slashes (/) for include-statements not backslashes (\), i.e.

    #include <opencv2\core.hpp> // Bad!
    #include <opencv2/core.hpp> // Good!
  2. In your check

    if (!image.data) { ... } 

    do not assume that image.data is set to NULL or nullptr for empty images. Instead check

    if (!image.empty()) { ... }
  3. Make sure that calls to cv::imshow(...) are followed by a call to cv::waitKey( /* delay in ms or 0 to wait for user input */ ), cf. the note in the OpenCV reference.

  4. while (1); -- is that intentional? What you want is probably cv::waitKey( 0 ) (see 3.).

UPDATE:


  1. Make sure the vector rgb has been initialized to the number of channels, i.e.

    vector<Mat> rgb(image.channels());
    split(image, rgb);
    // ...

UPDATE 2:

Can you tell me what exactly the error meant ?

Three things:

  1. The default constructor of std::vector<T> creates an empty vector.
  2. Apparently, cv::split() expects the caller, i.e. you, to allocate data for the output. If you fail to do so, it's likely provoke a segmentation fault.
  3. For debug builds some compilers add padding or safety memory around objects in memory which is never to be touched. If this padding memory is altered at runtime, the program "knows" that something bad happened and throws an exception like the one you saw.

?php instead of ?

The two main reasons to avoid the short opening tag are

  1. Maximum portability - <?php will work on every PHP enabled server, but <? can be disabled
  2. It's identical to the opening of the XML preamble - could cause parsing or execution headaches

Debug assertion failed - debug_heap.cpp:996

To see what runtime library you are actually using, you need to select just one platform and configuration (the ones you are building for) from the dropdowns. The runtime library needs to be Multi-Threaded DLL (or Multi-Threaded Debug DLL for Debug builds) for both your app and your plugin, and the configuration you are building for (Debug or Release) also needs to match.

The memory allocation takes places when a plugin calls the function but deallocation is performed in the core app.

This is fragile. I would recommend both allocating and deallocating in the plugin or both in the app, if you can arrange it.



Related Topics



Leave a reply



Submit