我害怕提出问题,以防它变得愚蠢......但我试图搜索并且看不到同样的情况。
我正在将std :: vector改造成一些主要是C风格的现有遗留代码。我们下一个未发布一两年的主要版本将放弃许多遗留代码。但就目前而言,我们的工作方式是,每个项目都会根据规格为客户重新编译。有些项目是在Visual Studio 2008上,有些是2010年,等等。我正在编写的我添加的std :: vector代码在使用2013编译时没有明显的问题,但是,在运行VS 2008 SP1时,我在STL代码中崩溃了。 / p>
现有代码中包含一个struct和一个固定大小的数组:
class{
public:
int rno;
int adrs;
bool integ_pending;
} RTUref;
typedef std::vector <RTUref> RTUlist;
typedef struct {
char device[64];
int port;
RTUlist RTU;
// more stuff...
} Connect_Info;
因此,我的基本目标是摆脱RTU阵列的硬编码大小限制。所以,我已经修改过它:
pct->RTU.clear();
使用我们自己的内存管理器分配Connect_Info结构。除了它应该比使用malloc()和free()更有效之外,不了解它。我猜测RTU的构造函数没有被调用,因为它包含在我们自己的内存管理器分配的数据中吗?
尽管如此,我调整数组大小的代码,将值放入数组中至少似乎都可以正常工作。但是,当我打电话给.clear()时,我在STL中发生了崩溃。正如我所说,只有我使用2008年。如果我使用2013年,我不会那么崩溃。
假设pct是指向已分配的Connect_Info结构的指针,则为:
if (pct->RTU.size() > 0)
pct->RTU.clear();
在VS 2008上生成崩溃。我可以调整大小并向元素添加元素。我甚至试图添加一个我不清楚的检查,除非尺寸大于零,如下:
pct->RTU = RTUlist();
我仍然清楚地看到了崩溃。
所以,我做了有根据的猜测,我需要调用一个构造函数。但是,我不太清楚如何做到这一点。但是,在分配Connect_Info结构的代码中,我尝试添加这样的构造函数代码:
ArrayList
它编译。但是,然后我在那条线上的STL发生了崩溃。
我还没有尝试构建一个小的包含测试程序,因为我甚至不确定如果没有我们的内存管理器,我将能够重现该问题。但是,如果这是我需要做的,我会尝试。我想也许有人可能会看到我做错了什么。我对STL很新手。
答案 0 :(得分:0)
一点背景:C ++中有一个名为&#34; POD Type&#34; (或&#34;普通旧数据类型&#34;)。
有冗长的规则,但基本上可能在分配,解除分配或副本上做特殊事情的事情不是POD类型。最初的Connect_Info是POD类型,因为它在那些时候没有做过特殊的事情而且没有任何非POD成员。
但是,因为你添加了一个std :: vector(不是一个POD类型,因为它必须在分配,释放,复制等方面做特殊事情(因为它分配内存)), Connect_Info不是POD类型。
可以使用malloc
安全地分配POD类型,并使用free
取消分配,因为他们不会做特殊事情。但是,非POD类型不能(除非您在C ++编程几年后首先看到的极少数情况下)会被分配。
C只有POD类型,因此malloc是完全可以接受的。您可以选择几种方法:
int main ( ... )
{
Connect_Info * info = new Connect_Info() ;
std::cout << info->port << std::endl ;
delete info ;
}
或者
Connect_Info * makeOne ()
{
void * ptr = malloc ( sizeof(Connect_Info) ) ;
if ( ! ptr ) return 0 ;
return new (ptr) Connect_Info () ; // "In-Place constructor"
}
void deleteOne ( Connect_Info * info )
{
if ( ! ptr ) return ;
info = info->~Connect_Info() ; // manually call its destructor with the weirdest syntax ever
// Note: I'm not 100% sure this call to 'free' is right because the in-place new can return a different pointer, but I don't know how to the get the original back
free ( static_cast<void*>(info) ) ;
}
int main ( ... )
{
Connect_Info * info = makeOne ()
std::cout << info->port << std::endl ;
deleteOne ( info ) ;
}
如果你有可用的提升(或C ++ 11,你可能没有),这是一个更好的选择(并且只使用提升的标题组件):
boost::shared_ptr<Connect_Info> makeOne ()
{
return boost::make_shared<Connect_Info> () ;
}
int main ( ... )
{
boost::shared_ptr<Connect_Info> info = makeOne ()
std::cout << info->port << std::endl ;
// nothing else: shared_ptr takes care of that for you
}
(如果你有C ++ 11,请使用std :: shared_ptr和std :: make_shared)