2010-03-03 73 views
2

在我的模板功能,我有以下代码:堆腐败问题

TypeName myFunction() 
{ 

    TypeName result; 
    void * storage = malloc(sizeof(TypeName)); 

    /*Magic code that stores a value in the space pointed to by storage*/ 

    result = *(TypeName *)storage; 

    free(storage); 
    return result; 
} 

这会导致error.If我不调用free()函数的“检测出堆损坏”,误差不发生,但我担心我正在创建一个内存泄漏。如何返回“存储”的值然后取消分配内存?

+1

线索在“假设”一词中。什么是'sizeof Typename'? – 2010-03-03 17:30:03

+3

你的错误可能在“魔法代码”中。我们可以偷看吗? – 2010-03-03 17:31:27

回答

1

什么:

TypeName myFunction() { 
    TypeName result; 
    void* storage = &result; 

    /*Magic code that stores a value in the space pointed to by storage*/ 

    return result; 
} 

在这里,所有的变量将被存储在堆栈上,所以你不应该遇到堆相关的问题(这依赖于你的“神奇”的代码做什么)。

有没有理由将您的storage阵列与result分开?如果结果将被简单地复制到result中,那么更有意义(恕我直言)只使用一个对象(并且根据需要保留指向它的void*指针或根据需要保留指定&result)。

如果有一个理由使用一个单独的storageresult,你会使用TypeName storage = new TypeNamedelete,而不是malloc(4)free可能获得更好的milage。

+0

我试试看,坦率地说我把结果和存储分开的习惯: 每次我写一个新函数,我放入的第一行是 型的结果; 返回结果; 所以IDE停止抱怨:) 编辑:完美的作品:)感谢一堆,我想这显示了我有与参考:)是多么真实的生活经验:)) – 2010-03-03 18:41:06

+0

是的,让我们用堆栈腐败替换堆腐败为后者很难注意到...... – sbk 2010-03-03 18:45:20

+0

请详细说明,你认为这个动作会引入什么问题?我真的没有看到可能对堆栈造成的危害,所以如果你有一些想法,它会帮助你我很多:)) – 2010-03-03 19:04:45

2

不要这样称呼它:

TypeName result; 
void * storage = malloc(4); 

你应该把它

TypeName result; 
void * storage = malloc(sizeof(TypeName)); 

反正代码看起来很奇怪:)

+0

这不是实际的代码,它是造成我的问题的一个小缩放模型:)你是完全正确的,不应该有魔法“4”在任何数据库周围徘徊:)) – 2010-03-03 18:32:44

3

你并不需要分配存储 ,你可以将你的结果变量转换成一个可以实现你魔法的函数。像这样的东西。

void magic(void *buffer) 
{ 
    // magic stuff 
} 

TypeName foo() 
{ 
    TypeName result; 
    magic(&result); 
    return result; 
} 

或者当然你可以有你的类型名结构设置为位字段或任何你的魔码操作...

+0

+1阅读问题,挖掘过去的机制,并提出最简单的解决方案。 – 2010-03-03 17:53:43

+0

是的,通常这将是明智的做法...但是正如它经常发生的那样,我无法在我的情况下这样做:S一些魔法代码涉及汇编和堆栈操作,所以我实际上无法再调用其他函数有:S:S – 2010-03-03 18:35:13

0

你为什么malloc 4个字节,但浇铸的类型名称TypeName?这绝对看起来很奇怪!

其他答案暗示你是什么......!

希望这会有所帮助, 最好的问候, 汤姆。

1

我觉得你的困惑就在于这一行:

void * storage = malloc(4); 

看起来你是要为4个字节的指针分配空间,但是这不是你需要做什么。让我们打破行分为两个步骤:

void * storage;   // This allocates 4 bytes for a variable of type "pointer to void" 
storage = malloc(4); // This allocates 4 _more_ bytes and sets "storage" to their address. 

我假设从Typename型到使用这种效果分配给storage内存变量“神奇”的代码拷贝数据:

memcpy(storage, data_from_a_Typename_variable, sizeof(Typename)); 

因此,如果sizeof(Typename)大于分配给storage的4个字节,您将看到堆损坏错误。

至于其他的答案表明,你需要做的是为Typename可变分配足够的空间,这样的:

void * storage = malloc(sizeof(Typename)); 

但是,正如Liz Albin建议,你已经在一个Typename分配空间result因此将&result(void *) &result传递给魔术功能会更简单。