【问题标题】:malloc: error checking and freeing memorymalloc:错误检查和释放内存
【发布时间】:2010-04-04 14:12:26
【问题描述】:

我正在使用 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);  
}

上面只是我的代码的一个sn-p,但是当我添加错误检查部分(包含在上面的if语句中)时,我得到了很多Visual Studio 2008的编译时错误。正是这个错误检查产生所有错误的部分。我做错了什么?

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

free(z1);
z1 = NULL;

第二行z1 = NULL有必要吗?

我收到 102 个错误...嗯,MVS2008 在 102 处停止错误。错误的类型为:

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

并且 this 指向 if 语句中结束的 } 之后。

ARRAY_SIZE 相当大。我把它定义为

#define ARRAY_SIZE 2500001

我上面的完整代码太长了。但是我有一个较小的代码,它给了我相同的行为。抱歉格式化。我好像没弄好。

#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;
}

【问题讨论】:

  • 错误信息是什么? ARRAY_SIZE 有多大? MSVS 2008 是否支持long double? (我真的不认为最后一个是问题,但请检查所有内容。)您是否包含定义 NULL 的标头? (对于malloc() 和exit() 和&lt;stdio.h&gt;,对于printf(),您同时需要&lt;stdlib.h&gt;。)您所做的大部分事情看起来都是正确的,所以是上下文造成了麻烦。
  • 具体是什么错误?
  • 谢谢大家。不,我没有定义 NULL。我不知道如何定义它。我在帖子中发布了一些错误。
  • 你能发布你包含的标准标题吗?应通过 stdio.h 为您定义 NULL。
  • 我正在使用 stdio.h、math.h 和 stdlib.h。 “conio”在以下答案之一中提供的小代码在我的机器上运行良好。

标签: c malloc


【解决方案1】:

代码中的问题

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

  1. 您试图在函数的“中间”定义变量。 C 不允许这样做。您必须在一开始就定义所有变量。这就是给你的原因
    error C2143: syntax error : missing ';' before 'type'
    错误。
  2. 函数声明也是如此(需要在函数的顶部)。

因此,将代码更改为以下代码即可:

#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;
}

其他几点

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

  1. 正如我之前所说,使用consts 来定义常量而不是#defines。
  2. 正确定义main() - 即int main() {... 而不仅仅是没有返回类型的main()。它适用于 C,但不适用于 C++,我认为它的风格不好。 (为什么我应该假设函数返回 int 如果什么都没说?为什么不 void?)
  3. 然后,您应该从main() 显式返回一个值。
  4. 我更喜欢在 main() 之外声明 void f(long double fa[], long double fb[], long double fA, long double fB); 函数原型。
  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) {。

这样你的代码就变成了:

#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;
}  

我认为更好。


第一次发帖

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

#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;
}

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

顺便说一句,比起#define,更喜欢const。

【讨论】:

  • 哇,您的更正版本运行良好。在 Matlab 编程十年后,我刚刚重新开始使用 c。你的建议对我很有价值,我非常感谢他们。我还在等待我要购买的 2 c 编程教科书。非常感谢您耐心地向我解释良好的编程实践。
  • 顺便说一句,在一个不相关的问题上,我做错了什么,只有部分代码出现在灰色窗口中?使代码格式正确的正确方法是什么?谢谢
  • 没问题。格雷码窗口有点问题(我花了好几次才把它写在我的帖子中),但最好的方法是先从编辑器中粘贴代码,选择它,然后单击“101”按钮。如果您查看your post,您会注意到#include... 之前只有三个空格,并且您需要四个空格才能正确格式化。
【解决方案2】:

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

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

【讨论】:

  • 谢谢。我在我的问题中提出了一些额外的信息。
【解决方案3】:

如果分配了z1,您可能需要检查代码的其他位置。将其设置为NULL 是一种很好的方式来判断没有为指针分配内存。

【讨论】:

  • 谢谢。 z1 正在分配,因为我的代码运行良好,没有用于错误检查的 if 语句。
猜你喜欢
  • 1970-01-01
  • 2018-06-13
  • 2021-04-28
  • 1970-01-01
  • 2014-11-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-12
相关资源
最近更新 更多