【问题标题】:Use function to create and free 2D array in C使用函数在 C 中创建和释放二维数组
【发布时间】:2019-01-11 13:16:07
【问题描述】:

我参考下面的网址练习二维动态数组: https://thispointer.com/allocating-and-deallocating-2d-arrays-dynamically-in-c-and-c/

我的代码:

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

int** create_2d_arr(int row_size,int colum_size)
{
    int** array = (int**)malloc(sizeof(int*)*row_size);
    for (int i = 0; i < row_size; i++)
        array[i] = (int*)malloc(sizeof(int)*colum_size);  
    return array;
}

void free_2d_arr(int** matrix,int row_size, int colum_size) {
    for (int i = 0; i < row_size; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

int main(int argc, char const *argv[])
{
    int row=3,cloum=2;
    int** arr_2d = create_2d_arr(row,cloum);

    arr_2d[0,0]=4;
    arr_2d[0,1]=5;

    arr_2d[1,0]=6;
    arr_2d[1,1]=7;

    arr_2d[2,0]=8;
    arr_2d[2,1]=9;

    for(int i=0;i<row;i++)
    for(int j=0;j<cloum;j++)
    printf("arr_2d[%d,%d] = %d \n",i,j,arr_2d[i,j]);

    free_2d_arr(arr_2d,row,cloum);

    return 0;
}

但是编译后执行时出现错误:

arr_2d[0,0] = 8 
arr_2d[0,1] = 9 
arr_2d[1,0] = 8 
arr_2d[1,1] = 9 
arr_2d[2,0] = 8 
arr_2d[2,1] = 9 
[1]    9300 segmentation fault (core dumped)  ./t

只有 arr_2d[2,0]=8 arr_2d[2,1]=9 是正确的。 我不明白我的代码哪里错了。 有人帮我吗?


续订

感谢您的回复。 但是在我将arr_2d[2,0]=8 修改为rr_2d[2][0]=8 之后...

result of printf is
arr_2d[0][0] = -267545984
arr_2d[0][1] = -267545952
arr_2d[1][0] = -267545984

...

编译器警告

t.c:38:47: warning: expression result unused [-Wunused-value]
    printf("arr_2d[%d,%d] = %d \n",i,j,arr_2d[i,j]);
                                              ^
t.c:38:40: warning: format specifies type 'int' but the argument has type
      'int *' [-Wformat]
    printf("arr_2d[%d,%d] = %d \n",i,j,arr_2d[i,j]);
                            ~~         ^~~~~~~~~~~
2 warnings generated.

我的编译器是clang,即使我使用gcc

=========

已解决

修改后:

printf("arr_2d[%d,%d] = %d \n",i,j,arr_2d[i,j]);

=>

printf("arr_2d[%d,%d] = %d \n",i,j,arr_2d[i],[j]);

正常工作。 非常感谢大家。

【问题讨论】:

  • arr_2d[0,0]=4; -> arr_2d[0][0]=4;
  • 您的编译器针对此代码向您发出了多少编译器警告?
  • 我怀疑你没有在printf中更改它。
  • 您是否使用标志 -Wall 来打开额外的警告。我会建议。
  • 嗨,Osiris,感谢您的提示。它工作正常。

标签: c arrays


【解决方案1】:

你不能像这样访问数组的值

arr_2d[x,y];

你必须使用这种类型的语法

arr_2d[x][y];

【讨论】:

  • 其实可以,但不是很有帮助的方式...stackoverflow.com/questions/34098166/…
  • 我不认为你可以,逗号运算符的作用,它只是评估每个部分并返回最后评估的部分,所以 arr_2d[2,23,6,23,56,2] 是有点没用,您可以只使用 arr_2d[2] 并且您将拥有相同的东西。此外,如果它是一个二维数组, arr_2d[x,y] 将返回一个数组 int/char..
  • [...它只是评估每个部分并返回最后评估的部分...],所以你可以。
【解决方案2】:

arr_2d[x,y] 等价于arr_2d[y]

在分配和访问中使用arr_2d[x][y]

在 C(或 C++)a,b,c .., z 计算 a 然后 b .. 然后 z 并返回 z 的值


所以:

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

int** create_2d_arr(int row_size,int colum_size)
{
    int** array = (int**)malloc(sizeof(int*)*row_size);
    int i;
    for ( i = 0; i < row_size; i++)
        array[i] = (int*)malloc(sizeof(int)*colum_size);  
    return array;
}

void free_2d_arr(int** matrix,int row_size, int colum_size) {
  int i;
    for ( i = 0; i < row_size; i++) {
        free(matrix[i]);
    }
    free(matrix);
}

int main(int argc, char const *argv[])
{
    int row=3,cloum=2;
    int** arr_2d = create_2d_arr(row,cloum);

    arr_2d[0][0]=4;
    arr_2d[0][1]=5;

    arr_2d[1][0]=6;
    arr_2d[1][1]=7;

    arr_2d[2][0]=8;
    arr_2d[2][1]=9;

    int i,j;
    for( i=0;i<row;i++)
    for( j=0;j<cloum;j++)
    printf("arr_2d[%d][%d] = %d \n",i,j,arr_2d[i][j]);

    free_2d_arr(arr_2d,row,cloum);

    return 0;
}

结果是:

arr_2d[0][0] = 4 
arr_2d[0][1] = 5 
arr_2d[1][0] = 6 
arr_2d[1][1] = 7 
arr_2d[2][0] = 8 
arr_2d[2][1] = 9 

【讨论】:

  • 好的,但是修改 arr_2d[0][0]=4;arr_2d[0][1]=5;....
  • arr_2d[0][0] = -267545984 arr_2d[0][1] = -267545952 ...(printf的结果)
  • @D.Wei 你确定你把所有的[a,b] 都改成了[a][b] 吗?我在你的程序上做,它可以写: 4 ,5 ... 8, 9 前缀 arr_2d[..][..]
  • 嗨布鲁诺,看看我的更新
  • @D.Wei 我编辑了我的答案以放置我执行的更正版本
【解决方案3】:

正确的语法是

arr_2d[i][j] = n;

我从未见过像 arr_2d[i,j] 这样的东西,如果有人向我们解释一下,我会非常满意。

我的猜测是它相当于arr_2d[j],但我不确定。

编辑:精度:您应该将所有 arr_2d[i,j](如 arr_2d[0,0])更改为新语法

【讨论】:

  • 它可能来自 matlab 之类的东西。其中 (i,j) 是规则的。但是方括号我也没见过
  • @hetepeperfan 是的,应该是这样......我的意思是我从未在 C 中见过它;)
【解决方案4】:

以下建议的代码:

  1. 干净编译
  2. 执行所需的功能
  3. 将我的 cmets 合并到 OPs 问题中
  4. 为了便于阅读,插入适当的空格:括号内、大括号内、分号后、逗号后、C 运算符周围
  5. 使用size_t 而不是int 以避免编译器警告关于intsize_t 之间的转换,尤其是在调用calloc()malloc()

现在,建议的代码:

#include <stdio.h>
#include <stdlib.h>   // exit(), EXIT_FAILURE


// prototypes
void free_2d_arr( int** matrix, size_t row_size, size_t colum_size );


int** create_2d_arr( size_t row_size, size_t colum_size )
{
    int** array = calloc( row_size, sizeof( int* ) );
    if( !array )
    {
        perror( "malloc failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    for ( size_t i = 0; i < row_size; i++ )
    {
        array[ i ] = malloc( sizeof(int) * colum_size );  
        if( !array[ i ] )
        {
            perror( "malloc failed" );
            free_2d_arr( array, row_size, colum_size ); 
            exit( EXIT_FAILURE );
        }
    }
    return array;
}


void free_2d_arr( int** matrix, size_t row_size, size_t colum_size ) 
{
    (void)colum_size;
    for ( size_t i = 0; i < row_size; i++ ) 
    {
        free( matrix[ i ] );
    }
    free( matrix );
}


int main( void )
{
    size_t row = 3;
    size_t cloum = 2;
    int** arr_2d = create_2d_arr( row, cloum );

    arr_2d[ 0 ][ 0 ] = 4;
    arr_2d[ 0 ][ 1 ] = 5;

    arr_2d[ 1 ][ 0 ] = 6;
    arr_2d[ 1 ][ 1 ] = 7;

    arr_2d[ 2 ][ 0 ] = 8;
    arr_2d[ 2 ][ 1 ] = 9;

    for( size_t i=0; i < row; i++ )
    {
        for( size_t j=0; j < cloum; j++ )
        {
            printf( "arr_2d[%lu,%lu] = %d \n", i, j, arr_2d[ i ][ j ] );
        }
    }

    free_2d_arr( arr_2d, row, cloum );

    return 0;
}

运行建议的代码会导致:

arr_2d[0,0] = 4 
arr_2d[0,1] = 5 
arr_2d[1,0] = 6 
arr_2d[1,1] = 7 
arr_2d[2,0] = 8 
arr_2d[2,1] = 9 

但请注意,以下语句:

size_t row = 3;
size_t cloum = 2;

实际上是程序的参数,23 是常量和“神奇”数字。 “魔术”数字是没有基础的数字。 “神奇”数字使代码更难理解、调试等。建议使用#define 语句或enum 语句为这些“神奇”数字赋予有意义的名称,然后在整个代码中使用这些有意义的名称

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-01-28
    • 2020-01-18
    • 2011-08-05
    • 1970-01-01
    • 2015-02-21
    相关资源
    最近更新 更多