In one of my c++ functions I am calling ab demangle. I want to deallocate result after changing that to string. Here is the code:
const char * realName;
string name;
const std::type_info &ti = typeid(*this);
realName = abi::__cxa_demangle(ti.name(), 0, 0, &status);
name= realName;
int index =name.find_last_of(':');
name = name.substr(index+1, name.length()-index-1);
free((void *) realName);
The code is running without problem but eclipse compiler is not happy and showing an error for using free: "Function 'free' could not be resolved".
I tried to use delete instead of free.
delete realName;
The code is running without problem and eclipse compiler is happy, however when I am profiling code with valgrind, I am getting a profiling error:
Mismatched free() / delete / delete []
So my question is:
1- Should I use free in c++ or shall I use just delete, delete []
2- If I should not use free why valgrind giving me an error
3- If I should use free why eclipse cdt comipler is giving me a compile error but when I am running code everything is ok.
4- is my code has correct style based on c++11? or is it a combination of c and old c++?
Should I use free in C++ or shall I use just delete, delete[]?
You should use the function or the operator that matches the allocation. When you allocate memory for your own use, you should use new/new[] for allocation, and delete/delete[] for deallocation.
When the memory to be deallocated comes from other sources, such as __cxa_demangle, you should read the documentation to see what functionality needs to be used on deallocation. The documentation for your function states that
the demangled name is placed in a region of memory allocated with malloc.
Therefore, you must use free to free it.
If I should use free why Eclipse cdt compiler is giving me a compile error but when I am running code everything is OK.
Function free is defined in <cstdlib> header. You need to add this header to your cpp file to make sure you code compiles fine.
You have to use free as the documentation says use free.
Perhaps you need to include the correct header file and library.
#include <stdlib.h> and maybe -lC
Related
I am looking for a way to track memory allocations in a C++ program. I am not interested in memory leaks, which seem to be what most tools are trying to find, but rather creating a memory usage profile for the application. Ideal output would be either a big list of function names plus number of maximum allocated bytes over time or better yet, a graphical representation of the heap over time. Horizontal axis is time, vertical axis heap space. Every function would get it's own color and draw lines according to allocated heap bytes. Bonus points for identifying allocated object types as well.
The idea is to find memory bottlenecks/to visualize what functions/threads consume the most memory and should be targetted for further optimization.
I have briefly looked at Purify, BoundsChecker and AQTime but they don't seem to be what I'm after. Valgrind looks suitable, however, I'm on Windows. Memtrack looks promising, but requires significant changes to the source code.
My google skills must have failed me, cause it doesn't seem to be such an uncommon request? All the needed information to create a tool like that should be readily available from the program's debug symbols plus runtime API calls - no?
Use Valgrind and its tool Massif. Its example output (a part of it):
99.48% (20,000B) (heap allocation functions) malloc/new/new[], --alloc-fns, etc.
->49.74% (10,000B) 0x804841A: main (example.c:20)
|
->39.79% (8,000B) 0x80483C2: g (example.c:5)
| ->19.90% (4,000B) 0x80483E2: f (example.c:11)
| | ->19.90% (4,000B) 0x8048431: main (example.c:23)
| |
| ->19.90% (4,000B) 0x8048436: main (example.c:25)
|
->09.95% (2,000B) 0x80483DA: f (example.c:10)
->09.95% (2,000B) 0x8048431: main (example.c:23)
So, you will get detailed information:
WHO allocated the memory (functions: g(), f(), and main() in above example); you also get complete backtrace leading to allocating function,
to WHICH data structure the memory did go (no data structures in above example),
WHEN it happened,
what PERCENTAGE of all allocated memory it is (g: 39.7%, f: 9.95%, main: 49.7%).
Here is Massif manual
You can track heap allocation as well as stack allocation (turned off by default).
PS. I just read that you're on Windows. I will leave the answer though, because it gives a picture of what you can get from a possible tool.
Microsoft have well documented memory tracking functions. However, for some reason they are not really well-known in the developer community. These are CRT debug functions. Good starting point will be CRT Debug Heap functions.
Check the following links for more details
Heap state reporting functions
Tracking heap allocation requests. Probably this is the functionality that you are looking for.
For a generic C++ memory tracker you will need to overload the following:
global operator new
global operator new []
global operator delete
global operator delete []
any class allocators
any in-place allocators
The tricky bit is getting useful information, the overloaded operators only have size information for allocators and memory pointers for deletes. One answer is to use macros. I know. Nasty. An example - place in a header which is included from all source files:
#undef new
void *operator new (size_t size, char *file, int line, char *function);
// other operators
#define new new (__FILE__, __LINE__, __FUNCTION__)
and create a source file with:
void *operator new (size_t size, char *file, int line, char *function)
{
// add tracking code here...
return malloc (size);
}
The above only works if you don't have any operator new defined at class scope. If you do have some at class scope, do:
#define NEW new (__FILE__, __LINE__, __FUNCTION__)
and replace 'new type' with 'NEW type', but that requires changing a lot of code potentially.
As it's a macro, removing the memory tracker is quite straightforward, the header becomes:
#if defined ENABLED_MEMORY_TRACKER
#undef new
void *operator new (size_t size, char *file, int line, char *function);
// other operators
#define NEW new (__FILE__, __LINE__, __FUNCTION__)
#else
#define NEW new
#endif
and the implementation file:
#if defined ENABLED_MEMORY_TRACKER
void *operator new (size_t size, char *file, int line, char *function)
{
// add tracking code here...
return malloc (size);
}
endif
Update: to the answer of #Skizz
Since C++20, we can use std::source_location instead of macros like __FILE__ and __LINE__.
(As this is a major simplification, I believe that it deserves a seperate answer).
On Xcode, you can use Instruments to track allocations, VM usage, and several other parameters. Mostly popular among iOS developers, but worth a try.
On Mac OS X, you can use the code profiling tool Shark to do this, IIRC.
"A graphical representation of the heap over time" - close to what you are looking for is implemented in Intel(R) Single Event API, details can be found in this article (its rather big to put it here).
It shows you timeline of per-block-size allocations and allows to add additional mark up to your code to understand the whole picture better.
The Visual Studio IDE has built-in heap profiling support (since 2015), which is probably the easiest to start with. It has graphical views of heap usage over time, and can track allocations by function/method.
Measure memory usage in Visual Studio
The CRT also has debug and profile support, which is more detailed and more low-level. You could track the data and plot the results using some other tool:
CRT Debug Heap Details
In particular, look at _CrtMemCheckpoint and related functions.
I have a C# program mainly for UI which uses a c++ dll for the logic.
Lately i switched compiler from platform toolset VS 2012(v110) to VS 2017(v141), since then i recieve an exception(without description) everytime it trys to release a std:: collection.
Example:
{
std::string str = "";
}
I tried the same with std::map, std::stack and std::list all of these get a exception in the file xmemory0 within the function _Deallocate. This does not happen when i create a simple c++ console application, so i guess it has something todo with c++ used within a c# application.
Using a custom Allocater for std::list seemed to work but i would like to know the reason why upgrading the compiler leads to such a problem.
Finaly i found the cause, between 2012 and 2017 they added a new delete operator. So for allocating the string it used our new operator and for deallocating it used the standard delete operator.
(do not ask why we override those operators(not my decision)...)
I have a C++ client to a C++/CLI DLL, which initializes a series of C# dlls.
This used to work. The code that is failing has not changed. The code that has changed is not called before the exception is thrown. My compile environment has changed, but recompiling on a machine with an environment similar to my old one still failed. (EDIT: as we see in the answer this is not entirely true, I was only recompiling the library in the old environment, not the library and client together. The client projects had been upgraded and couldn't easily go back.)
Someone besides me recompiled the library, and we started getting memory management issues. The pointer passed in as a String must not be in the bottom 64K of the process's address space. I recompiled it, and all worked well with no code changes. (Alarm #1) Recently it was recompiled, and memory management issues with strings re-appeared, and this time they're not going away. The new error is Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
I'm pretty sure the problem is not located where I see the exception, the code didn't change between the successful and failing builds, but we should review that to be complete. Ignore the names of things, I don't have much control over the design of what it's doing with these strings. And sorry for the confusion, but note that _bridge and bridge are different things. Lots of lines of code missing because this question is already too long.
Defined in library:
struct Config
{
std::string aye;
std::string bee;
std::string sea;
};
extern "C" __declspec(dllexport) BridgeBase_I* __stdcall Bridge_GetConfiguredDefaultsImplementationPointer(
const std::vector<Config> & newConfigs, /**< new configurations to apply **/
std::string configFolderPath, /**< folder to write config files in **/
std::string defaultConfigFolderPath, /**< folder to find default config files in **/
std::string & status /**< output status of config parse **/
);
In client function:
GatewayWrapper::Config bridge;
std::string configPath("./config");
std::string defaultPath("./config/default");
GatewayWrapper::Config gwtransport;
bridge.aye = "bridged.dll";
bridge.bee = "1.0";
bridge.sea = "";
configs.push_back(bridge);
_bridge = GatewayWrapper::Bridge_GetConfiguredDefaultsImplementationPointer(configs, configPath, defaultPath, status);
Note that call to library that is crashing is in the same scope as the vector declaration, struct declaration, string assignment and vector push-back
There are no threading calls in this section of code, but there are other threads running doing other things. There is no pointer math here, there are no heap allocations in the area except perhaps inside the standard library.
I can run the code up to the Bridge_GetConfiguredDefaultsImplementationPointer call in the debugger, and the contents of the configs vector look correct in the debugger.
Back in the library, in the first sub function, where the debugger don't shine, I've broken down the failing statement into several console prints.
System::String^ temp
List<CConfig^>^ configs = gcnew List<CConfig ^>((INT32)newConfigs.size());
for( int i = 0; i< newConfigs.size(); i++)
{
std::cout << newConfigs[i].aye<< std::flush; // prints
std::cout << newConfigs[i].aye.c_str() << std::flush; // prints
temp = gcnew System::String(newConfigs[i].aye.c_str());
System::Console::WriteLine(temp); // prints
std::cout << "Testing string creation" << std::endl; // prints
std::cout << newConfigs[i].bee << std::flush; // crashes here
}
I get the same exception on access of bee if I move the newConfigs[i].bee out above the assignment of temp or comment out the list declaration/assignment.
Just for reference that the std::string in a struct in a vector should have arrived at it's destination ok
Is std::vector copying the objects with a push_back?
std::string in struct - Copy/assignment issues?
http://www.cplusplus.com/reference/vector/vector/operator=/
Assign one struct to another in C
Why this exception is not caught by my try/catch
https://stackoverflow.com/a/918891/2091951
Generic AccessViolationException related questions
How to handle AccessViolationException
Programs randomly getting System.AccessViolationException
https://connect.microsoft.com/VisualStudio/feedback/details/819552/visual-studio-debugger-throws-accessviolationexception
finding the cause of System.AccessViolationException
https://msdn.microsoft.com/en-us/library/ms164911.aspx
Catching access violation exceptions?
AccessViolationException when using C++ DLL from C#
Suggestions in above questions
Change to .net 3.5, change target platform - these solutions could have serious issues with a large mult-project solution.
HandleProcessCorruptedStateExceptions - does not work in C++, this decoration is for C#, catching this error could be a very bad idea anyway
Change legacyCorruptedStateExceptionsPolicy - this is about catching the error, not preventing it
Install .NET 4.5.2 - can't, already have 4.6.1. Installing 4.6.2 did not help. Recompiling on a different machine that didn't have 4.5 or 4.6 installed did not help. (Despite this used to compile and run on my machine before installing Visual Studio 2013, which strongly suggests the .NET library is an issue?)
VSDebug_DisableManagedReturnValue - I only see this mentioned in relation to a specific crash in the debugger, and the help from Microsoft says that other AccessViolationException issues are likely unrelated. (http://connect.microsoft.com/VisualStudio/feedbackdetail/view/819552/visual-studio-debugger-throws-accessviolationexception)
Change Comodo Firewall settings - I don't use this software
Change all the code to managed memory - Not an option. The overall design of calling C# from C++ through C++/CLI is resistant to change. I was specifically asked to design it this way to leverage existing C# code from existing C++ code.
Make sure memory is allocated - memory should be allocated on the stack in the C++ client. I've attempted to make the vector be not a reference parameter, to force a vector copy into explicitly library controlled memory space, did not help.
"Access violations in unmanaged code that bubble up to managed code are always wrapped in an AccessViolationException." - Fact, not a solution.
but it was the mismatch, not the specific version that was the problem
Yes, that's black letter law in VS. You unfortunately just missed the counter-measures that were built into VS2012 to turn this mistake into a diagnosable linker error. Previously (and in VS2010), the CRT would allocate its own heap with HeapAlloc(). Now (in VS2013), it uses the default process heap, the one returned by the GetProcessHeap().
Which is in itself enough to trigger an AVE when you run your app on Vista or higher, allocating memory from one heap and releasing it from another triggers an AVE at runtime, a debugger break when you debug with the Debug Heap enabled.
This is not where it ends, another significant issue is that the std::string object layout is not the same between the versions. Something you can discover with a little test program:
#include <string>
#include <iostream>
int main()
{
std::cout << sizeof(std::string) << std::endl;
return 0;
}
VS2010 Debug : 32
VS2010 Release : 28
VS2013 Debug : 28
VS2013 Release : 24
I have a vague memory of Stephen Lavavej mentioning the std::string object size reduction, very much presented as a feature, but I can't find it back. The extra 4 bytes in the Debug build is caused by the iterator debugging feature, it can be disabled with _HAS_ITERATOR_DEBUGGING=0 in the Preprocessor Definitions. Not a feature you'd quickly want to throw away but it makes mixing Debug and Release builds of the EXE and its DLLs quite lethal.
Needless to say, the different object sizes seriously bytes when the Config object is created in a DLL built with one version of the standard C++ library and used in another. Many mishaps, the most basic one is that the code will simply read the Config::bee member from the wrong offset. An AVE is (almost) guaranteed. Lots more misery when code allocates the small flavor of the Config object but writes the large flavor of std::string, that randomly corrupts the heap or the stack frame.
Don't mix.
I believe 2013 introduced a lot of changes in the internal data formats of STL containers, as part of a push to reduce memory usage and improve perf. I know vector became smaller, and string is basically a glorified vector<char>.
Microsoft acknowledges the incompatibility:
"To enable new optimizations and debugging checks, the Visual Studio
implementation of the C++ Standard Library intentionally breaks binary
compatibility from one version to the next. Therefore, when the C++
Standard Library is used, object files and static libraries that are
compiled by using different versions can't be mixed in one binary (EXE
or DLL), and C++ Standard Library objects can't be passed between
binaries that are compiled by using different versions."
If you're going to pass std::* objects between executables and/or DLLs, you absolutely must ensure that they are using the same version of the compiler. It would be well-advised to have your client and its DLLs negotiate in some way at startup, comparing any available versions (e.g. compiler version + flags, boost version, directx version, etc.) so that you catch errors like this quickly. Think of it as a cross-module assert.
If you want to confirm that this is the issue, you could pick a few of the data structures you're passing back and forth and check their sizes in the client vs. the DLLs. I suspect your Config class above would register differently in one of the fail cases.
I'd also like to mention that it is probably a bad idea in the first place to use smart containers in DLL calls. Unless you can guarantee that the app and DLL won't try to free or reallocate the internal buffers of the other's containers, you could easily run into heap corruption issues, since the app and DLL each have their own internal C++ heap. I think that behavior is considered undefined at best. Even passing const& arguments could still result in reallocation in rare cases, since const doesn't prevent a compiler from diddling with mutable internals.
You seem to have memory corruption. Microsoft Application Verifier is invaluable in finding corruption. Use it to find your bug:
Install it to your dev machine.
Add your exe to it.
Only select Basics\Heaps.
Press Save. It doesn't matter if you keep application verifier open.
Run your program a few times.
If it crashes, debug it and this time, the crash will point to your problem, not just some random location in your program.
PS: It's a great idea to have Application Verifier enabled at all times for your development project.
I need to use C++ memory allocation routines in my Objective C iOS project. However, compiler does not recognize new/delete operators yielding Use of undeclared identifier "new".
char *armsciiBuffer = new char[numberOfUnicodeChars];
...
delete [] armsciiBuffer;
What is the workaround here? I could use malloc, but new/delete would have been much better.
Compile the code as Objective-C++. Either add the -x obj-c++ compiler flag, or name your source file Foo.mm.
Background: We are using Keil to compile our NXP LPC2458 project. There are numerous tasks that are being run on Keil’s RealView RTOS. There is stack space created, which is being allocated to each task. There is no HEAP created by default, and I want to avoid it since we can't afford the code-space overhead and the cost of "garbage collecting"
Objective: Use C++ in the embedded code without using the heap. Keil provides the #pragma (__use_no_heap) which prevents malloc() and free() calls to be linked.
Solution: I tried creating a Singleton with a private static pointer. My hopes were that the new() would not be called since I declared dlmData as static in the getDLMData(). For some reason, the linker still states that malloc() and free() are being called. I have thoughts of a private operator new () and a private operator delete() , and then declaring the dlmData as static within the overloaded function. It is not working for some reason. WHAT AM I DOING WRONG?
//class declaration
class DataLogMaintenanceData
{
public:
static DataLogMaintenanceData* getDLMData();
~DataLogMaintenanceData()
{ instanceFlag = FALSE; }
protected:
DataLogMaintenaceData(); //constructor declared protected to avoid poly
private:
static Boolean instanceFlag;
static DataLogMaintenceData *DLMData;
}
//set these to NULL when the code is first started
Boolean DataLogMaintenanceData::instanceFlag = FALSE;
DataLogMaintenanceData *DataLogMaintenaceData::DLMData = NULL;
//class functions
DataLogMaintenanceData *DataLogMaintenanceData::getDLMData()
{
if (FALSE == instanceFlag)
{
static DataLogMaintenanceData dlmData;
DLMData = &dlmData;
instanceFlag = TRUE;
return DLMData;
}
else
{
return DLMData;
}
}
void InitDataLog ( void )
{
DataLogMaintenanceData *dlmData;
dlmData = DataLogMaintenanceData::getDLMData();
// to avoid dlmData warning
dlmData = dlmData;
}
//ACTUAL TASK
__task DataLog()
{
.. .. .. code to initialize stuff
InitDataLog();
.. .. ..more stuff
}
For some reason, the only way I can get this to compile, is to create a heap space and then allow the malloc() and free() calls to be compiled into the project. As expected, the “static”ally defined object, dlmData, resides in the RAM space allocated to the dataLog.o module (i.e. it doesn’t live in the HEAP).
I can’t figure out, and I have checked Google, what am I missing? Is it possible in C++ to bypass malloc() and free() when compiling pure objects? I know I can replace the RTOS’s implementation of malloc() and free() to do nothing, but I want to avoid compiling in code that I won’t use.
Probably some of the code we aren't seeing calls a function that calls malloc behind the scenes.
From http://www.keil.com/support/man/docs/armlib/armlib_CJAIJCJI.htm you can use --verbose --list=out.txt on the link line to get details about the malloc caller.
Included in the Keil installation is a set of PDFs... one of the documents (document ID DUI0475A) is titled "Using ARM C and C++ Libraries and Floating-Point Support". It discusses use of the heap (and preventing its use) in several places.
Specifically, check out section 2.64 "Avoiding the ARM-supplied heap and heap-using library functions", lots of good information there. The interesting text in that section:
You can reference the __use_no_heap or __use_no_heap_region symbols in
your code to guarantee that no heap-using functions are linked in from
the ARM library.
__use_no_heap guards against the use of malloc(), realloc(), free(),
and any function that uses those functions. For example, calloc() and
other stdio functions.
__use_no_heap_region has the same properties as __use_no_heap, but in
addition, guards against other things that use the heap memory region.
For example, if you declare main() as a function taking arguments, the
heap region is used for collecting argc and argv.
Since your question is about how prevent malloc() from being called / used, that might put you on the right track.
From the code you've posted I cannot see anything that would like to allocate the memory on the heap. Are there any implicit conversions taking place somewhere? What if you compile without this class at all?
What you could do:
1) Run under debugger (assuming you can build a runnable image, maybe on an emulator), set a breakpoint in malloc and examine the stack
2) Provide your own malloc and free to make linker happy, then repeat step 1.
You may find that you need to link against a different version of C runtime startup. In the worst case if number of calls to malloc/free is limited you can roll out your own version which will give the callers some preallocated memory - but hopefully this will not be neccessary.