这个功能有什么问题?

问题描述:

我想malloc和goto的关系有问题。或者,我猜想这里有一些记忆力的浪费或内存的腐败。希望有人能指出我确切的错误。 当我编译它不给我任何错误,但是,我的前辈坚持认为我有一个错误。这个功能有什么问题?

#define FINISH() goto fini; 

BOOL Do() 
{ 

    BOOL stat; 
    UINT32 ptr; 
    int err; 

    ptr = (UINT32)malloc(1000); 


    free((void*)ptr); 

fini: 
    return stat; 
} 
+15

'#定义FINISH()转到FINI;'哦,上帝怜悯 – orlp 2012-02-25 21:18:31

+3

请不要使用'goto'。请不要在宏内隐藏“goto”。 – 2012-02-25 21:20:27

+0

这段代码是否编译?我想不是。 – 2012-02-25 21:20:30

这里是我的代码

  • err != ERROR_SUCCESS此功能将导致内存泄漏发现的问题。它将跳过free呼叫。
  • 您正在将返回的malloc存储到32位的位置。这不是一个便携式解决方案。在64位平台上,这会对您的程序造成严重破坏,因为您会截断地址。如果您必须在这里使用非指针类型,请改用size_t(尽管我会建议使用整数类型的指针)
  • 本地stat未在此处明确指定。如果err != ERROR_SUCCESS您正在返回垃圾。它需要始终分配一个值。最简单的方法是提供一个默认值。
  • 你不检查malloc返回值和一个隐藏NULL指针可能传递到Fun2

下面是与编辑的功能,我建议

BOOL Do() 
{ 

    BOOL stat = FALSE; 
    size_t ptr = 0; 
    int err; 

    ptr = (UINT32)malloc(1000); 
    err = Fun1(); 

    if (err != ERROR_SUCCESS || ptr == 0) 
     FINISH(); 
    else 
     stat = Fun2(ptr); 

fini: 
    free((void*)ptr); 
    return stat; 
} 
+0

我认为''stat'也不会初始化,以防'if'的结果为真。 – Muggen 2012-02-25 21:22:10

+0

你不需要'ptr!= 0'检查:'0'转换为空指针,'free()'为空指针安全 – Christoph 2012-02-25 21:22:46

+0

@Muggen谢谢,刚刚修复在最近编辑 – JaredPar 2012-02-25 21:23:10

malloc返回指针。您正在将一个指针指向一个整数,但指针和整数不需要具有相同的表示。例如,指针大小可能是64位,并不适合您的整数。

此外,对象stat可以在您的函数中使用未初始化。没有明确的初始化,对象stat在声明后有一个不确定的值。

+0

这是一个正确的答案。 Downvoter会照顾一个解释吗? – 2012-02-25 21:20:55

+0

@ ErnestFriedman-Hill,你认为'(UINT32)malloc(1000)'在做什么? – 2012-02-25 21:21:43

+0

我的不好,倒行逆转,评论删除。还有这么多其他问题没有出现在我身上。 – 2012-02-25 21:22:52

我们不知道这是应该做的,但如果Fun1()不返回ERROR_SUCCESS,然后ptr永远不会被释放。据推测,这是你老板谈论的错误。

您的指针转换为uint32_t,然后再回来。这将擦除指针值的上半部分。

无论你做什么,你都没有编译该代码。它有一个语法错误。

if(foo) 
    bar;; 
else 
    baz 

检查您的构建系统。

我的整体评论和在C中工作的一般经验法则......如果你必须做指针转换,问问自己:你真的必须吗?你真正需要做指针的时间非常少见。更常见的是,当人们使用指针转换时,因为他们在理解上存在一些差距,不清楚他们想要做什么或应该做什么,并且试图使编译器警告无声。

ptr = (UINT32)malloc(1000); 

非常不好!如果你对这个“指针”做任何事情,如果它在64位平台上工作,你将会非常幸运。将指针留作指针类型。如果您绝对必须将它们存储在一个整数中,请使用uintptr_t,该值应保证足够大。

我说你可能一直在试图做的事:

// Allocate 1,000 32-bit integers 
UINT32 *ptr = (UINT32*)malloc(1000 * sizeof(UINT32)); 

然而,即使是对于C代码,一个奇怪的C和C++混合形式差。与C++不同,在C你可以只取一void *和隐含它带到任何指针类型:

// Allocate 1,000 32-bit integers 
UINT32 *ptr = malloc(1000 * sizeof(UINT32)); 

最后,

free((void*)ptr); 

铸造到void*是另一大红旗,经常一个迹象,表明作者不知道他们在做什么。一旦你改变ptr是一个实际的指针类型,只是这样做:

free(ptr);