这个函数有什么问题吗?
我猜想malloc和goto的关系有问题。或者,我猜想这里发生了一些内存浪费或内存损坏。希望有人能指出我确切的错误。 当我编译时,它没有给我任何错误,但是,我的前辈坚持认为我有一个错误。
#define FINISH() goto fini;
BOOL Do()
{
BOOL stat;
UINT32 ptr;
int err;
ptr = (UINT32)malloc(1000);
free((void*)ptr);
fini:
return stat;
}
I guess there is problem with the relation of malloc and goto. Or, I guess there is some wastage of memory or corruption of memory happening out here. Hope, someone can point to me the exact error.
When I compile its not giving me any error, but, my senior is insisting that I have a mistake.
#define FINISH() goto fini;
BOOL Do()
{
BOOL stat;
UINT32 ptr;
int err;
ptr = (UINT32)malloc(1000);
free((void*)ptr);
fini:
return stat;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
以下是我在代码中发现的问题:
free
调用。malloc
的返回值存储到 32 位位置。这不是一个便携式解决方案。在 64 位平台上,这会对您的程序造成严重破坏,因为您会截断地址。如果您必须在此处使用非指针类型,请使用size_t
(尽管我建议使用整型类型的指针)stat
并未在此处明确分配。如果err != ERROR_SUCCESS
,您将返回垃圾。它需要始终被赋予一个值。最简单的方法是提供默认值。malloc
的返回值,并可能将隐藏的NULL
指针传递给Fun2
这是包含我建议的编辑的函数
Here are the problems I spotted in the code
err != ERROR_SUCCESS
this function will leak memory. It will jump over thefree
call.malloc
into a 32 bit location. This is not a portable solution. On 64 bit platforms this will wreak havoc on your program as you'd be truncating the address. If you must use a non-pointer type here usesize_t
instead (although I would reccomend a pointer over an integral type)stat
is not definitively assigned here. You are returning garbage iferr != ERROR_SUCCESS
. It needs to always be assigned a value. Easiest way is provide a default.malloc
and potentially pass a hiddenNULL
pointer intoFun2
Here's the function with the edits I suggested
malloc
返回一个指针。您正在将指针强制转换为整数,但指针和整数不需要具有相同的表示形式。例如,指针大小可能是 64 位,并且不适合您的整数。此外,对象
stat
也可以在函数中未初始化时使用。如果没有显式初始化,对象stat
在声明后将具有不确定的值。malloc
returns a pointer. You are casting a pointer to an integer but pointers and integers are not required to have the same representation. For example the pointer size could be 64-bit and would not fit in your integer.Also the object
stat
can be used not-initialized in your function. Without an explicit initialized the objectstat
has an indeterminate value after its declaration.我们不知道这应该做什么,但如果
Fun1()
不返回ERROR_SUCCESS
,则ptr
永远不会被释放。想必这就是你老板所说的错误。We have no idea what this is supposed to do, but if
Fun1()
doesn't returnERROR_SUCCESS
, thenptr
is never freed. Presumably, that's the error your boss is talking about.您正在将指针转换为
uint32_t
并再次转换回来。这会擦除指针值的上半部分。You are converting a pointer to an
uint32_t
and back again. This erases the upper half of your pointer value.无论你做什么,你都没有编译该代码。它有一个语法错误。
检查您的构建系统。
Whatever you do, you are not compiling that code. It has a syntax error.
Check your build system.
我的总体评论以及使用 C 语言工作的一般经验法则...如果您必须进行指针转换,请问问自己:您真的必须这样做吗?老实说,您真正需要进行指针转换的情况非常罕见。更常见的是,当人们使用指针强制转换时,因为他们在理解上存在一些差距,不太清楚他们正在尝试做什么或应该做什么,并且试图消除编译器警告。
非常糟糕!如果你用这个“指针”做任何事情,如果它能在 64 位平台上运行,你将非常幸运。将指针保留为指针类型。如果您绝对必须将它们存储在整数中,请使用保证足够大的
uintptr_t
。我想说你可能一直在尝试这样做:
然而,即使这对于 C 代码来说也是很糟糕的形式,它是一种奇怪的 C 和 C++ 混合体。与 C++ 不同,在 C 中,您可以只使用
void *
并隐式地将其转换为任何指针类型:最后,
强制转换为
void*
是另一个大危险信号,通常是一个标志作者不知道他们在做什么。将ptr
更改为实际的指针类型后,只需执行以下操作:My overall comment, and a general rule of thumb for working in C... If you have to do pointer casts, ask yourself: do you really have to? The times you will honestly need to do pointer casts are exceedingly rare. What's much more common is when people use pointer casts because they have some gap in understanding, don't have it very clear what they're trying to do or should be doing, and are trying to silence a compiler warning.
Very bad! If you do anything with this "pointer", you will be very lucky if it works on 64-bit plaforms. Leave pointers as pointer types. If you absolutely must store them in an integer, use
uintptr_t
which is guaranteed to be large enough.I'd say you might have been trying to do:
However even that is poor form for C code, a weird C and C++ hybrid. Unlike C++, in C you can just take a
void *
and implicitly bring it to any pointer type:Lastly,
Casting to
void*
is another big red flag, frequently a sign that the author doesn't know what they're doing. Once you changeptr
to be an actual pointer type, just do this: