这个函数有什么问题吗?

发布于 2025-01-08 20:41:00 字数 295 浏览 0 评论 0原文

我猜想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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

提赋 2025-01-15 20:41:00

以下是我在代码中发现的问题:

  • 当 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;
}

Here are the problems I spotted in the code

  • When err != ERROR_SUCCESS this function will leak memory. It will jump over the free call.
  • You are storing the return of 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 use size_t instead (although I would reccomend a pointer over an integral type)
  • The local stat is not definitively assigned here. You are returning garbage if err != ERROR_SUCCESS. It needs to always be assigned a value. Easiest way is provide a default.
  • You don't check the return value of malloc and potentially pass a hidden NULL pointer into Fun2

Here's the function with the edits I suggested

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;
}
最单纯的乌龟 2025-01-15 20:41:00

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 object stat has an indeterminate value after its declaration.

一身骄傲 2025-01-15 20:41:00

我们不知道这应该做什么,但如果 Fun1() 不返回 ERROR_SUCCESS,则 ptr 永远不会被释放。想必这就是你老板所说的错误。

We have no idea what this is supposed to do, but if Fun1() doesn't return ERROR_SUCCESS, then ptr is never freed. Presumably, that's the error your boss is talking about.

煮茶煮酒煮时光 2025-01-15 20:41:00

您正在将指针转换为 uint32_t 并再次转换回来。这会擦除指针值的上半部分。

You are converting a pointer to an uint32_t and back again. This erases the upper half of your pointer value.

可是我不能没有你 2025-01-15 20:41:00

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

if(foo)
  bar;;
else
  baz

检查您的构建系统。

Whatever you do, you are not compiling that code. It has a syntax error.

if(foo)
  bar;;
else
  baz

Check your build system.

凤舞天涯 2025-01-15 20:41:00

我的总体评论以及使用 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);

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.

ptr = (UINT32)malloc(1000);

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:

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

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:

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

Lastly,

free((void*)ptr);

Casting to void* is another big red flag, frequently a sign that the author doesn't know what they're doing. Once you change ptr to be an actual pointer type, just do this:

free(ptr);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文