【问题标题】:How to avoid memory leak where function returning an array如何避免函数返回数组的内存泄漏
【发布时间】:2016-02-14 05:14:56
【问题描述】:

在下面的代码中,指针A在调用函数copy()之前有不同的地址。一旦copy()被执行,指针A就得到了copy()中声明的指针B的地址>。因此,在 main() 内,当 free(A) 执行时,它会释放分配给 copy( )。现在的问题是如何解除分配在 main() 内的指针 A ?以下代码中是否存在内存泄漏?如何预防?

代码如下:

#define size 10
int *copy(int *A){
int i;
int *B = (int *)calloc(size,sizeof(int));
printf("address of B=%p\n",B);
for(i=0;i<size;i++){
       B[i]=A[i]+1;
    }
for(i=0;i<size;i++){
   printf("%d ",B[i]);
   }
 printf("\n ");
 return B;
 }

 int main(){
     int i;
     int *A = (int *)calloc(size,sizeof(int));
     printf("address of A before copy()=%p\n",A);

     for(i=0;i<size;i++){
        A[i] = i;
        }
        A=copy(A);
      printf("address of A after copy()=%p\n",A);
     for(i=0;i<size;i++){
         printf("%d ",A[i]);    
         }
     printf("\n");
     free(A);
     return 0;
     }

这是输出:

   address of A before copy()=0x1e64010
   address of B=0x1e64040
   1 2 3 4 5 6 7 8 9 10 
   address of A after copy()=0x1e64040
   1 2 3 4 5 6 7 8 9 10 

【问题讨论】:

    标签: c pointers memory-leaks


    【解决方案1】:

    以下代码是否存在内存泄漏?

    是的,这些行可能存在内存泄漏:

    int *A = (int *)calloc(size,sizeof(int));
    
    int *A = copy(A);   // <-- Do NOT allocate and then point the pointer to somewhere else
    

    那是因为您为A 分配了内存,然后您将A 指向其他地方,从而失去了释放最初分配内存的句柄。

    注意:

    • 不过,在这种特殊情况下,您可能会侥幸成功,因为它发生在 main() - 并且当程序退出时,操作系统本身可能会释放内存。
    • 不过一般来说,这种代码会导致内存泄漏,尤其是函数不是main()的时候。此外,让操作系统为您进行清理是一种不好的做法。

    如何解除分配在 main() 中的指针 A ?

    如何让它发挥作用 - 这里有一个建议:

    • main() 内声明第二个指针B
    • 然后调用copy 复制/修改原始数组中的内容。

    代码应如下所示:

     int *A = (int *)calloc(size,sizeof(int));
    
     // Initialize A
     for( i=0;i<size;i++ )
     {
        A[i] = i;
     }
    
     // Copy A to B, and modify the content.
     int *B = copy(A);   // <-- 2nd pointer
    

    最后,free 两个指针:

    free( A );
    free( B );
    

    【讨论】:

    • 感谢您的回答!我在这里有一个疑问,在 main() 中释放 B 之前,用 copy(A) 更新 A 的最佳方法是什么?
    • 如果您只想修改A,那么不要在copy 函数中返回int *,只需使用void copy(int *A) - 这样您就可以修改@987654336 @ 直接地。还要把函数名改成别的,不是copy,也许update()会更好。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-13
    • 1970-01-01
    相关资源
    最近更新 更多