动态内存中的free()

问题描述 投票:0回答:2

我的用法正确吗?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;
}
c arrays dynamic-memory-allocation free
2个回答
4
投票

只要你的指针由 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);

3
投票

在这个循环中

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 
© www.soinside.com 2019 - 2024. All rights reserved.