C语言 2D全动态阵列的内存泄漏

2cmtqfgy  于 2023-08-03  发布在  其他
关注(0)|答案(1)|浏览(75)

我的任务是根据以下接口实现一个简单的API,用于完全动态的2D数组。

const int m = 2;
const int n = 3;
int **array = allocate_array (m, n);
assert (array != NULL);
for (unsigned int i = 0; i < m; i++)
{
  for (unsigned int j = 0; j < n; j++)
  {
    array[i][j] = i*10 + j;
  }
}
print_array (array, m, n);
free_and_nullify_array (&array, m);
printf("array points to %p\n", array);

/*
OUTPUT: 
 0  1  2
10 11 12
array points to (nil)
*/

字符串
我只需要实现3个特定的功能作为程序的一部分。
虽然我已经尝试实现这些函数,但程序目前表明存在内存泄漏。尽管我做了很多努力,但我还是无法确定代码中发生这些内存泄漏的确切位置。

//! allocate an m x n fully-dynamic 2D array
int** allocate_array (int m, int n)
{
    int ** arr = malloc (sizeof(int *) * m);
    if (!arr)
    {
        free(arr);
        arr = NULL;
        return NULL;
    }
    
    for (int i = 0; i < n; i++)
    {
        arr[i] = malloc (sizeof(int) * n);
        if (!arr[i])
        {
            free(arr[i]);
            arr[i] = NULL;
            return NULL;
        }
    }
    
    return arr;
}

//! free *array, a full-dynamic 2D array with m rows
//! and set its pointer to NULL
void free_and_nullify_array (int ***p_array, int m)
{
    for (int i = 0; i < m; i++)
    {
        free((*p_array)[i]);
        (*p_array)[i] = NULL;
    }
    
    free(*p_array);
    *p_array = NULL;
}

//! print an m x n fully-dynamic array
//! use one line per row, 2 digits per integer ("%2d"), one space
void print_array (int **array, int m, int n)
{
    for (int i = 0; i < m; i++)
    {
        for (int j = 0; j < n; j++)
        {
            printf("%2d ", array[i][j]);
        }
        printf("\n");
    }
}

qvk1mo1f

qvk1mo1f1#

对于初学者来说,这个for循环中有一个错字

for (int i = 0; i < n; i++)
                ^^^^^
{
    arr[i] = malloc (sizeof(int) * n);
    if (!arr[i])
    {
        free(arr[i]);
        arr[i] = NULL;
        return NULL;
    }
}

字符串
您需要使用变量m而不是n
这个for循环中的另一个问题是,如果没有成功分配内存,那么之前为指针数组和一维整数数组分配的内存就不会被释放。
你应该写例如

//! allocate an m x n fully-dynamic 2D array
int ** allocate_array( int m, int n )
{
    int **arr = malloc( m * sizeof( int * ) );

    if ( arr != NULL )
    {
        int i = 0;

        while ( i < m && ( arr[i] = malloc( n * sizeof( int ) ) ) != NULL ) i++;

        if ( i != m )
        {
            for ( int j = 0; j < i; j++ ) free( arr[j] );
            free( arr );
            arr = NULL;
        }
    }
    
    return arr;
}


通常,您应该检查参数的值是否为正值。与其使用有符号整数类型int作为参数,不如使用无符号整数类型size_t
比如说

//! allocate an m x n fully-dynamic 2D array
int ** allocate_array( size_t m, size_t n )
{
    int **arr = NULL;

    if ( m != 0 && n != 0 )
    {
        int **arr = malloc( m * sizeof( int * ) );

        if ( arr != NULL )
        {
            size_t i = 0;

            while ( i < m && ( arr[i] = malloc( n * sizeof( int ) ) ) != NULL ) i++;

            if ( i != m )
            {
                for ( size_t j = 0; j < i; j++ ) free( arr[j] );
                free( arr );
                arr = NULL;
            }
        }
    }

    return arr;
}


在函数free_and_nullify_array中,

(*p_array)[i] = NULL;


是多余的。你可以把它拿走了。

相关问题