C语言 malloc:错误检查和释放内存

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/2574642/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-02 05:02:50  来源:igfitidea点击:

malloc: error checking and freeing memory

cmalloc

提问by yCalleecharan

I'm using malloc to make an error check of whether memory can be allocated or not for the particular array z1. ARRAY_SIZE is a predefined with a numerical value. I use casting as I've read it's safe to do so.

我正在使用 malloc 对是否可以为特定数组 z1 分配内存进行错误检查。ARRAY_SIZE 是一个预定义的数值。我使用投射,因为我读过这样做是安全的。

long double *z1 = (long double *)malloc(sizeof (long double) * ARRAY_SIZE);  
if(z1 == NULL){  
   printf("Out of memory\n");  
   exit(-1);  
}

The above is just a snippet of my code, but when I add the error checking part (contained in the if statement above), I get a lot of compile time errors with visual studio 2008. It is this error checking part that's generating all the errors. What am I doing wrong?

以上只是我的代码片段,但是当我添加错误检查部分(包含在上面的 if 语句中)时,我在 Visual Studio 2008 中遇到了很多编译时错误。正是这个错误检查部分生成了所有错误。我究竟做错了什么?

On a related issue with malloc, I understand that the memory needs to be deallocated/freed after the variable/array z1 has been used. For the array z1, I use:

关于 malloc 的一个相关问题,我知道在使用变量/数组 z1 后需要释放/释放内存。对于数组 z1,我使用:

free(z1);
z1 = NULL;

Is the second line z1 = NULLnecessary?

第二行是z1 = NULL必要的吗?

I get 102 errors...well MVS2008 stops the errors at 102. The errors are of type:

我收到 102 个错误……好吧,MVS2008 在 102 处停止了错误。错误类型为:

error C2143: syntax error : missing ';' before 'type'  
error C2065: 'L' : undeclared identifier
// this error repeats for all my identifiers

and this points right after the closing } in the if statement.

这点紧跟在 if 语句中的 } 之后。

ARRAY_SIZE is quite large. I define it as

ARRAY_SIZE 相当大。我将其定义为

#define ARRAY_SIZE 2500001

My full above code is too long. But I have a smaller code which is giving me the same behavior. Sorry for the formatting. I can't seem to get it right.

我上面的完整代码太长了。但是我有一个较小的代码,它给了我相同的行为。抱歉格式化。我似乎无法正确理解。

#include stdio.h //note I have the actual < > in my code
#include stdlib.h
#include math.h
#define ARRAY_SIZE 11
#define VECTOR_SIZE 5

main()
{
    long double *z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
    if(z == NULL){
        printf("Out of memory\n");
        exit(-1);
    }

    long double *k = (long double*) malloc(sizeof (long double) * VECTOR_SIZE);
    int i;
    long double A, B;
    void f(long double fa[], long double fb[], long double fA, long double fB);

    A = 0.5;
    B = 2;

    for(i = 0; i < VECTOR_SIZE; i++){
        k[i] = 0;
    }

    k[1] = 4;
    k[2] = 8;

    for(i = 0; i < ARRAY_SIZE; i++){
        z[i] = 0;
    }

    z[1] = 5;


    f(k, z, A, B);

    free(z);
    free(k);
    z = NULL;
    k = NULL;
}


void f(fa, fb, fA, fB)
long double fa[], fb[], fA, fB;
{
    fa[0] = fb[1]* fA;
    fa[1] = fa[1] - 1;
    fb[0] = 2* fB - fa[2];
    printf("fa[2] is 8 and is the same as *[fa + 2] and is  %3.3Le\n", *(fa + 2));
    printf("\nAddress of &fa[2] is %x\n", &fa[2]);
    printf("same address is fa + 2 is %x\n", fa + 2);
    return;
}

回答by conio

Problems in your code

您的代码中的问题

Allright. Now that you've provided all the code it's easier to explain your problems:

好的。现在您已经提供了所有代码,更容易解释您的问题:

  1. You're trying to define variables "in the middle" of your functions. C doesn't allow this. you have to define all your variables right at the start. That's what's giving you the
    error C2143: syntax error : missing ';' before 'type'
    errors.
  2. Same goes for the function declaration (needs to be at the top of the function).
  1. 您正在尝试在函数的“中间”定义变量。C 不允许这样做。您必须在开始时定义所有变量。这就是给你
    error C2143: syntax error : missing ';' before 'type'
    错误的原因。
  2. 函数声明也是如此(需要位于函数的顶部)。

Therefore, changing your code to the following makes it work:

因此,将您的代码更改为以下内容使其工作:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

#define ARRAY_SIZE 11
#define VECTOR_SIZE 5

main() {
    void f(long double fa[], long double fb[], long double fA, long double fB);

    long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
    long double* k = (long double*) malloc(sizeof (long double) * VECTOR_SIZE);
    int i;
    long double A, B;

    if (z == NULL) {
        printf("Out of memory\n");
        exit(-1);
    }

    A = 0.5;
    B = 2;

    for (i = 0; i < VECTOR_SIZE; i++) {
        k[i] = 0;
    }

    k[1] = 4;
    k[2] = 8;

    for (i = 0; i < ARRAY_SIZE; i++) {
        z[i] = 0;
    }

    z[1] = 5;

    f(k, z, A, B);

    free(z);
    free(k);
    z = NULL;
    k = NULL;
}

void f(fa, fb, fA, fB)  
long double fa[], fb[], fA, fB;  
{
    fa[0] = fb[1]* fA;
    fa[1] = fa[1] - 1;
    fb[0] = 2* fB - fa[2];

    printf("fa[2] is 8 and is the same as *[fa + 2] and is  %3.3Le\n", *(fa + 2));
    printf("\nAddress of &fa[2] is %x\n", &fa[2]);
    printf("same address is fa + 2 is %x\n", fa + 2);

    return;
}



A few other points

其他几点

Now I'll add a few more tips, that perhaps aren't strictly errors (meaning, they still compile...), but aren't very good coding practices:

现在我将添加更多提示,它们可能不是严格意义上的错误(意思是,它们仍然可以编译……),但不是很好的编码实践:

  1. As I said before, use consts to define constants rather than #defines.
  2. define main()properly - that is int main() {...rather than just main()without a return type. It works in C, but doesn't work in C++ and I consider it bad style. (Why the hell am I supposed to assume functions return int if nothing else is said? why not void?)
  3. Following that, you should explicitly return a value from main().
  4. I prefer declaring the void f(long double fa[], long double fb[], long double fA, long double fB);function prototype outside main().
  5. When defining functions use the modern syntax - the one you used in the prototype - rather than the ancient one:
    void f(fa, fb, fA, fB)
    long double fa[], fb[], fA, fB;
    {
    Should become:
    void f(long double fa[], long double fb[], long double fA, long double fB) {.
  1. 正如我之前所说,使用consts 来定义常量而不是#defines。
  2. main()正确定义- 这int main() {...不仅仅是main()没有返回类型。它适用于 C,但不适用于 C++,我认为它的风格很糟糕。(如果什么都没说,我为什么要假设函数返回 int ?为什么不是 void?)
  3. 之后,您应该显式地从 返回一个值main()
  4. 我更喜欢void f(long double fa[], long double fb[], long double fA, long double fB);main().
  5. 定义函数时使用现代语法——你在原型中使用的语法——而不是古老的语法:
    void f(fa, fb, fA, fB)
    long double fa[], fb[], fA, fB;
    {
    应该变成:
    void f(long double fa[], long double fb[], long double fA, long double fB) {

This way your code turns to:

这样你的代码就会变成:

#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void f(long double fa[], long double fb[], long double fA, long double fB);

int main() {
    const int ARRAY_SIZE = 11;
    const int VECTOR_SIZE = 5;

    long double* z = (long double*) malloc(sizeof (long double) * ARRAY_SIZE);
    long double* k = (long double*) malloc(sizeof (long double) * VECTOR_SIZE);

    int i;
    long double A, B;

    if (z == NULL) {
        printf("Out of memory\n");
        exit(-1);
    }

    A = 0.5;
    B = 2;

    for (i = 0; i < VECTOR_SIZE; i++) {
        k[i] = 0;
    }

    k[1] = 4;
    k[2] = 8;

    for (i = 0; i < ARRAY_SIZE; i++) {
        z[i] = 0;
    }

    z[1] = 5;

    f(k, z, A, B);

    free(z);
    free(k);
    z = NULL;
    k = NULL;

    return 0;
}

void f(long double fa[], long double fb[], long double fA, long double fB) {
    fa[0] = fb[1]* fA;
    fa[1] = fa[1] - 1;
    fb[0] = 2* fB - fa[2];

    printf("fa[2] is 8 and is the same as *[fa + 2] and is  %3.3Le\n", *(fa + 2));
    printf("\nAddress of &fa[2] is %x\n", &fa[2]);
    printf("same address is fa + 2 is %x\n", fa + 2);

    return;
}  

Which I think is better.

我认为哪个更好。



First Post

第一个帖子

Please provide all your code. I tested the following code on Visual C++ 2008 Express with "language extensions" disabled and level 4 warnings. It works just fine:

请提供您的所有代码。我在禁用“语言扩展”和 4 级警告的情况下在 Visual C++ 2008 Express 上测试了以下代码。它工作得很好:

#include <stdlib.h>
#include <stdio.h>

int main() {
    const int ARRAY_SIZE = 1024*1024;

    long double *z1 = (long double *)malloc(sizeof (long double) * ARRAY_SIZE);
    if (z1 == NULL) {
        printf("Out of memory\r\n");
        exit(-1);
    }

    printf("Awesome!\r\n");

    return 0;
}

Maybe you forgot an include, maybe you did something else wrong. The code snippet itself seems perfectly fine. The second error you described seems totally unrelated: error C2065: 'L' : undeclared identifier // this error repeats for all my identifiers

也许你忘记了一个包含,也许你做错了什么。代码片段本身看起来非常好。您描述的第二个错误似乎完全无关: error C2065: 'L' : undeclared identifier // this error repeats for all my identifiers

By the way, prefer constover #define.

顺便说一句,喜欢const#define

回答by cpalmer

Try #include-ing stdio.h and stdlib.h to make sure that NULL is actually defined.

尝试 #include-ing stdio.h 和 stdlib.h 以确保实际定义了 NULL。

And to answer your second question setting z1 to NULL is not necessary, though it will help you to make sure you never inadvertently try to use z1 after it's been free'd, since dereferencing a null pointer will crash. So its a good defensive thing to do, but not required.

并回答您的第二个问题,将 z1 设置为 NULL 不是必需的,尽管它会帮助您确保在 z1 被释放后不会无意中尝试使用它,因为取消引用空指针会崩溃。所以这是一个很好的防御性的事情,但不是必需的。

回答by zoli2k

You may need to check in other places of your code if z1is allocated. Setting it to NULLis a good way to tell that memory is not allocated for the pointer.

如果z1已分配,您可能需要检查代码的其他位置。将它设置为NULL是表明没有为指针分配内存的好方法。