我在Visual Studio 2015 sp3中使用C++.通过
#pragma init_seg(compiler)
Run Code Online (Sandbox Code Playgroud)
,我首先初始化一些静态变量(到内存管理). https://msdn.microsoft.com/en-us/library/7977wcck.aspx
但是还有
Run Code Online (Sandbox Code Playgroud)#pragma init_seg(compiler)
在wcerr.cpp(Microsoft Visual Studio 14.0\VC\crt\src\stl\wcerr.cpp)中,所以这些对象在我的对象之前初始化.
我可以wcerr.cpp通过任何编译/链接选项强制我的对象在对象之前被初始化吗?
c++ pragma static-variables visual-studio visual-studio-2015
更新:以下问题似乎取决于该-fwhole-program选项.
我一直在玩内存分配,我遇到了一个小小的谜团:在GCC(4.6)中,当我用[/] 编译时如何std::string分配它的内存[ edit-fwhole-program ]?
有以下测试程序:
#include <new>
#include <string>
#include <iostream>
#include <cstdlib>
void * operator new(std::size_t n) throw(std::bad_alloc)
{
void * const p = std::malloc(n);
if (p == NULL) throw std::bad_alloc();
std::cerr << "new() requests " << n << " bytes, allocated at " << p << ".\n";
return p;
}
void operator delete(void * p) noexcept
{
std::cerr << "delete() at " << p << ".\n";
std::free(p);
}
int main()
{ …Run Code Online (Sandbox Code Playgroud) 我有一个在基于ARM Cortex-M的MCU上运行的应用程序,用C和C++编写.我使用gcc并g++编译它,并希望完全禁用任何堆使用.
在MCU启动文件中,堆大小已经设置为0.除此之外,我还想禁止在代码中使用任何意外的堆.
换句话说,我想接头(和/或编译器),以给我一个错误时malloc,calloc,free功能或new,new[],delete,delete[]运营商使用.
到目前为止,我已经尝试过-nostdlib这样的问题undefined reference to _start.我也尝试过,-nodefaultlibs但是当我试着打电话时,我仍然没有抱怨malloc.这样做的正确方法是什么?
笔记:
多年来我一直避免尝试使用operator new做任何事情,因为我觉得它在Windows上是一个泥潭(特别是使用MFC).更不用说,除非有一个非常令人信服的理由混淆全局(甚至是类)新的和删除,否则不应该.
但是,我有一个讨厌的小内存损坏错误,我非常想跟踪它.我从CRT调试分配器获取消息,指示先前释放的内存被覆盖.此消息仅在稍后的分配调用期间显示,当它尝试重用块时(无论如何,我相信这是它的工作原理).
由于有问题的代码部分,错误消息和损坏点是非常不相关的.我所知道的是"某个地方覆盖了一些以前用一个空字节释放的内存." (我通过使用调试器并在几个不同的运行中观察调试堆引用的内存来确定这一点).
已经用尽了关于罪魁祸首的明显想法,我不得不尝试做一些更严谨的事情.在我看来,如果我可以使每个释放的块成为一个无访问的内存页面,那么编写器将立即被CPU的MMC捕获,这将是理想的!稍后再进行一些搜索,我发现有人在这些方面实现了一些东西:
http://www.codeproject.com/Articles/38340/Immediate-memory-corruption-detection
他的代码被埋没在大量的重新编码代码中,但提取核心概念非常简单,我已经这样做了.
我现在遇到的问题是MFC将新的redfines重新定义为DEBUG_NEW,然后进一步定义了一系列调试接口,直到CRT.此外,它确实定义了全局运算符new和delete.因此,就C++而言,"用户"试图将全局运算符new和delete替换为两次,因此我得到了一个链接器错误,其效果为'已定义的符号'.
环顾互联网,以及SO,我看到了一些有前途的文章,但没有一个最终对于替换MFC的全局运营商new/delete有任何积极意义.
如何正确替换全局new和delete运算符
是否可以在MFC应用程序的调试版本中替换内存分配器?
我已经知道了:
好吧,它提供了它提供的功能 - 比如让我首先沿着这条路走下去的信息.我现在知道腐败正在发生,但这非常糟糕!
我想提供的是保护分配(或者甚至只是保护重新分配).这显然可以通过使用大量虚拟地址空间并将每个分配隔离开来,这极大地浪费了内存.好吧,是的,当这是一个仅用于调试的代码时,无法看到它的缺点,就像现在这样的特殊用途时刻一样.
所以,我正在拼命寻求以下解决方案
有没有人知道答案,或者阅读的好文章可能会说明如何实现这些目标?
其他想法:
进一步的调查:
2012年5月3日更新:
我正在使用_CrtDumpMemoryLeaks来确定我们软件中的内存泄漏。我们在多线程应用程序中使用第三方库。该库确实存在内存泄漏,因此在我们的测试中,我们希望识别那些我们泄漏的信息,并丢弃那些我们无法控制的信息。
我们使用持续集成,因此始终会添加新的功能/算法/错误修复。
因此,问题是-是否存在一种安全的方法来识别那些属于我们的泄漏和属于第三方库的泄漏。我们虽然使用分配号,但这样安全吗?
我正在尝试new使用一些额外的信息来追踪内存泄漏.我知道,我可以new全局覆盖一个运算符,但我惊讶地发现我无法检索有关所分配对象类型的任何信息(如果我错了,请纠正我).显然,当您决定覆盖new运算符时,获取类型信息将是有益的.
例如,我已经实现了一个简单的通用版本new并delete使用了可变参数模板.
std::string to_readable_name(const char * str)
{
int status;
char *demangled_name = abi::__cxa_demangle(str, NULL, NULL, &status);
if(status == 0) {
std::string name(demangled_name);
std::free(demangled_name);
return name;
}
return "Unknown";
}
template <typename T, typename... Args>
T * generic_new(Args&&... args) throw (std::bad_alloc)
{
const std::size_t size = sizeof(T);
std::cout << "Allocating " << size << " bytes for " << to_readable_name(typeid(T).name()) << std::endl;
return new T(std::forward<Args>(args)...);
};
template<typename T>
void generic_delete(T* …Run Code Online (Sandbox Code Playgroud)