2017-10-06 96 views
0

我是使用C中的malloc的新手。我试图声明一个动态数组结构,然后释放它,类似于2D aray并释放它。我使用gcc来编译代码。声明和释放2D动态数组和结构数组

  1. 第一个问题是使用结构阵列的关于,

    struct OPinfo { 
    
         long NLocal; 
    
         double ReFrame,ImFrame,lcl_ReFrame,lcl_ImFrame,lcl_SqFrame; 
    
    }; 
    
    struct OPinfo *OPSTR; 
    
    
    void declare_local_structure() { 
         OPSTR = (struct OPinfo*) malloc(NBinsR * sizeof(struct OPinfo)); 
         int i =0; 
         while(i<NBinsR) { 
           OPSTR[i].NLocal = 0; 
           OPSTR[i].ReFrame = 0.0; 
           OPSTR[i].ImFrame = 0.0; 
           OPSTR[i].lcl_ReFrame = 0.0; 
           OPSTR[i].lcl_ImFrame = 0.0; 
           OPSTR[i].lcl_SqFrame = 0.0; 
           i++; 
         } 
    
    } 
    void free_local_structure() { 
         fprintf(stderr,"%d %d\n",*OPSTR,OPSTR); 
         free(OPSTR); 
    } 
    

表示没有指针意外的fprintf中(.. OPSTR)部分是给出在declare_local_structure()和free_local_structure(同地址)同时。如果我评论免费(OPSTR)部分,该计划运作良好。否则,它会运行,并在最后调用free_local_structure()时发出以下错误。 *错误在`./a.out':无():无效尺寸:0x0000000002d2fd40 *

  • 在同一程序中的另一部分,我使用的2D阵列指针,我宣布,中

    double **Gxy, **GxyRot; 
    Gxy = (double**) malloc((NBinsXY) * sizeof(double *)); 
    GxyRot = (double**) malloc((NBinsXY) * sizeof(double *)); 
    
    for(j=0; j<NBinsXY; j++) { 
         Gxy[j] = malloc(NBinsXY * sizeof(double)); 
         GxyRot[j] = malloc(NBinsXY * sizeof(double)); 
    } 
    
  • 和自由通过,

    for(l=0;l<NBinsXY;l++) { 
         free(Gxy[l]); 
         free(GxyRot[l]); 
    } 
    
    free(Gxy); 
    free(GxyRot); 
    

    这再次给SA我上面的错误,但如果我免费,

    free(*Gxy); 
    free(*GxyRot); 
    free(Gxy); 
    free(GxyRot); 
    

    该程序运行没有错误。

    错误在哪里?我尝试了“valgrind”,但无法理解输出。另一点是程序在编译C99时出错。 gcc -std=c99 *.c headers/*.h -lm

    +2

    什么是你的调用'declare_local_structure'和'free_local_structure'之间*做*?也许你在代码中写出了没有向​​我们展示的内容?至于Valgrind,使用调试信息(在构建时添加'-g'标志)并重新运行,Valgrind将能够显示它找到的问题的源文件和行号信息。如果你无法弄清楚,那么编辑你的问题以包含Valgrind的完整复制粘贴(作为文本)输出。 –

    +2

    将'-Wall -Wextra'添加到GCC命令行时会得到什么警告?至少应该有一个,因为你的'fprintf'调用是无效的(你不能将'* OPSTR'传递给'fprintf',并期望它正确地处理事情,特别是当你告诉它你传递一个数字时)我怀疑是什么导致了这个问题。 –

    +0

    感谢您的“-g”建议。二维数组声明中的Valarind错误。 “initialize_declare.c:32”是数组Gxy和GxyRot,大小为8的无效读取 == 2138 ==在0x401864:calculate_bin(calculation.c:125) == 2138 == by 0x401E36:calculate_for_frame(calculation.c: 168) == 2138 == by 0x40359E:main(main_function.c:72) == 2138 ==地址0x652c710在一个大小为8,000的块后分配16个字节 == 2138 ==在0x4C2DB9D:malloc( vg_replace_malloc.c:299) == 2138 == by 0x402CCA:declare_arrays(initialize_declare.c:32) == 2138 == by 0x403516:main(main_function.c:58) – haphaZard

    回答

    0

    我同意上面的意见,关于积极使用调试器,因为它会提供有关问题性质和位置的详细信息。

    关于使用C中[m][c]alloc时用C分配内存,(并不适用于C++)一般情况下,是(虽然仍然严格争论)it not necessary (or recommended)你投的回报。例如,以下内容:

    Gxy = (double**) malloc((NBinsXY) * sizeof(double *)); 
    

    应该写成:

    Gxy = malloc((NBinsXY) * sizeof(double *)); 
    if(Gxy)//and always test for success before using pointers created using malloc/calloc 
    { 
        ... 
    

    关于释放,规则是每次调用[m][c]alloc()必须有相应的同等数量的调用来free(...)。由于您使用的是循环分配内存,是有意义的使用一个免费期间以及:

    for(j=0; j<NBinsXY; j++) { 
        free(Gxy[j]); 
        free(GxyRot[j]); 
    } 
    free(Gxy); 
    free(GxyRot); 
    
    +0

    根据你的要求,投射回归可能会或可能不会是更好的风格。但是,它不会造成这种错误。 –

    +0

    @DanielH - 尽管仍然经常争论,但是在C中抛出或不抛弃calloc的返回问题并不是风格问题。这更多的是掩盖在尝试创建内存时可能发生的问题。这只适用于'C',而不是'C++',建议在这里建立返回。 – ryyker

    +0

    在你最后的代码示例中,在取消引用基于它们的指针之后,检查'Gxy'和'GxyRot'。如果你以后不打算检查它们,那么根本不值得检查它们。 –