动态内存中的 free()

free() in dynamic memory

我在下面的代码中使用 free() 正确吗?是内存泄漏吗?在主要部分而不是函数中使用 free() 是否有问题?如果是的话,有一个方法可以在函数中释放,而不是在 main 中?

此代码将一个数组复制到另一个数组中。

int *copy(const int *arr,int n);

int main(){
    int *p_arr1,*p_arr2;
    int n,i;

    printf("Insert size of array: ");
    scanf("%d",&n);

    p_arr1 = calloc(n,sizeof(int));

    for(i=0;i<n;i++){
        printf("Insert element %d of the array: ",i+1);
        scanf("%d",p_arr1+i);
    }

    p_arr2 = copy(p_arr1,n);

    for(i=0;i<n;i++){
        printf("%d ",*p_arr2);
        p_arr2++;
    }

    free(p_arr1);
    free(p_arr2);

    return 0;
}

int *copy(const int *arr,int n){
    int i;
    int *new;
    new = calloc(n, sizeof(int));
    for(i=0;i<n;i++){
        new[i] += arr[i];
    }

    return new;
}

只要你有malloc返回的指针(或者在你的情况下calloc)你可以随时随地将它传递给free,它不会必须在同一个函数中。

但是,在打印 p_arr2 内容的循环之后,函数内部不再有 calloc 返回的指针,因为您在循环中修改了指针。

您需要为循环使用临时指针变量:

int *p_arr2_tmp = p_arr2;
for (size_t i = 0; i < n; ++i)
{
    printf("%d ", *p_arr2_tmp);
    ++p_arr2_tmp;
}

// Now we can free the memory pointed to by the original p_arr2 pointer
free(p_arr2);

或者您可以改用简单的数组索引:

for (size_t i = 0; i < n; ++i)
{
    printf("%d ", p_arr2[i]);
}

// The pointer p_arr2 wasn't modified, so it can be passed to free
free(p_arr2);

在这个循环中

for(i=0;i<n;i++){
    printf("%d ",*p_arr2);
    p_arr2++;
}

指针 p_arr2 的值正在更改,因此在 free 调用中使用更改后的指针会导致未定义的行为。

你应该写

for(i=0;i<n;i++){
    printf("%d ", p_arr2[i] );
}

也不清楚为什么您在函数中使用复合运算符 += 而不是运算符 =。

new[i] += arr[i];

函数可以这样定义

int * copy( const int *arr, size_t n )
{
    int *new_arr = malloc( n * sizeof( int ) );

    if ( new_arr != NULL ) 
    {
        memcpy( new_arr, arr, n * sizeof( int ) );
    }

    return new_arr;
}

如果你想在输出新创建的数组的循环中使用指针,那么它可以像下面这样

for ( const int *p = p_arr2; p != p_arr2 + n; ++p )
{
    printf( "%d ",*p );
}
putchar( '\n' );

如果目标是编写一个仅使用指针并排除使用下标运算符和索引的程序,那么您的程序可以如下所示

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

int * copy( const int *arr, size_t n )
{
    int *new_arr = malloc( n * sizeof( int ) );

    if ( new_arr != NULL ) 
    {
        for ( int *p = new_arr; p != new_arr + n; ++p )
        {
            *p = *arr++;
        }
    }

    return new_arr;
}

int main(void) 
{
    size_t n;

    printf( "Insert size of array: " );
    scanf( "%zu", &n );

    int *p_arr1 = calloc( n, sizeof( int ) );

    for ( int *p = p_arr1; p != p_arr1 + n; ++p )
    {
        printf( "Insert element %d of the array: ", ( int )( p - p_arr1 + 1 ) );
        scanf( "%d", p );
    }

    int *p_arr2 = copy( p_arr1, n );

    if ( p_arr2 != NULL )
    {
        for ( const int *p = p_arr2; p != p_arr2 + n; ++p )
        {
            printf( "%d ",*p );
        }

        putchar( '\n' );
    }

    free( p_arr2 );
    free( p_arr1 );

    return 0;
}

程序输出可能看起来像

Insert size of array: 10
Insert element 1 of the array: 0
Insert element 2 of the array: 1
Insert element 3 of the array: 2
Insert element 4 of the array: 3
Insert element 5 of the array: 4
Insert element 6 of the array: 5
Insert element 7 of the array: 6
Insert element 8 of the array: 7
Insert element 9 of the array: 8
Insert element 10 of the array: 9
0 1 2 3 4 5 6 7 8 9