如何将函数中的二维数组赋给主函数?[duplicate]

hjzp0vay  于 2022-12-03  发布在  其他
关注(0)|答案(1)|浏览(122)

此问题在此处已有答案

How to pass 2D array (matrix) in a function in C?(4个答案)
18天前关闭。
我在函数arrayConstruction中有一个2D数组,我想把它交给主函数使用,它可以工作,但在那里检索到的值完全不一致。下面是我尝试这样做的结果:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <regex.h> 
#include <unistd.h>
#include <ctype.h>

void arrayConstruction(int nb_row, char** result, int (*givenArr)[2]){

    const char * separator = " ";
    char * strToken;
    char *outt;
    char *end;

    /* 1D array */
    int arrBuf[nb_row*2];
    /* 2D array */
    int (*myArr)[2] = (int(*)[2])arrBuf;
    int i;
    outt = strdup(*result);
    /* Store numbers as 1D array */
    strToken = strtok ( outt, separator );
    for (i = 0; i < nb_row*2 && strToken != NULL ; i++) {
        arrBuf[i] = (int)strtol(strToken, &end, 10);
        strToken = strtok ( NULL, separator);
    }

    givenArr = myArr;

}


int main(int argc, char **argv) 

{

char *result = 
" 2 1\n\
  3 2\n\
  5 2\n\
  5 4\n\
  6 1\n\
  6 2\n\
  7 1\n\
  7 3\n\
  7 4\n\
  8 1\n\
";

int nb_rows = 10;
int emptyArr[][2] ={0};
arrayConstruction(nb_rows, &result, emptyArr);

int i;
  for (i = 0; i < nb_rows; i++) {
    printf("%d---%d\n", emptyArr[i][0], emptyArr[i][1]);
}

}

我试图通过创建指向数组的指针来访问它,但它的值不正确。

gt0wga4j

gt0wga4j1#

givenArr = myArr;

在函数arrayConstruction中,只会改变局部变量givenArr的值,它是一个指针。它不会以任何方式改变原始数组emptyArr,因此函数main无法访问新值。
即使函数main确实以某种方式获得了对新值的访问,该值对main也是无用的,因为该值是dangling pointer,原因如下:
表达式myArr是指向数组arrBuf的第一个元素的指针,即&arrBuf[0]。但是,一旦函数arrayConstruction返回,整个数组arrBuf将不再存在,因为它是一个带有自动lifetime的局部数组。因此,一旦函数返回,指针将指向一个不存在的对象。因此指针是无用的。
因此,将数据存储在函数arrayConstruction的本地数组中是没有意义的。在函数main中声明数组更有意义,这样它的生存期就与函数main一样长。
在函数main中,您使用的是二维数组,但在函数arrayConstruction中,您同时使用了二维数组和一维数组。由于尝试将二维数组作为一维数组is not allowed in plain ISO C进行访问(尽管它在大多数平台上都能工作),最好决定是使用2D数组还是1D数组,并在整个程序中保持一致。
下面是一个使用1D数组的工作示例:

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

void arrayConstruction( int *nb_elements, int givenArr[], char *input )
{
    const char * separator = " ";
    char * strToken;
    char *outt;
    int i;

    outt = strdup( input );

    strToken = strtok ( outt, separator );

    for ( i = 0; i < *nb_elements && strToken != NULL; i++ )
    {
        givenArr[i] = strtol( strToken, NULL, 10 );
        strToken = strtok ( NULL, separator);
    }

    free( outt );

    *nb_elements = i;
}

int main( void )
{
    char *input =
        " 2 1\n"
        " 3 2\n"
        " 5 2\n"
        " 5 4\n"
        " 6 1\n"
        " 6 2\n"
        " 7 1\n"
        " 7 3\n"
        " 7 4\n"
        " 8 1\n"
    ;

    int arr[20] = {0};
    int nb_elements = sizeof arr / sizeof *arr;
    arrayConstruction( &nb_elements, arr, input );

    for ( int i = 0; i < nb_elements / 2; i++ )
    {
        printf( "%d---%d\n", arr[i*2+0], arr[i*2+1] );
    }
}

请注意,我是在使用strdup之后调用free的,而您在代码中没有这样做,这导致了memory leak
此程序具有以下输出:

2---1
3---2
5---2
5---4
6---1
6---2
7---1
7---3
7---4
8---1

下面是一个使用2D数组的工作示例:

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

void arrayConstruction( int *nb_rows, int givenArr[][2], char *input )
{
    const char * separator = " ";
    char * strToken;
    char *outt;
    int i;

    outt = strdup( input );

    strToken = strtok ( outt, separator );

    for ( i = 0; i < *nb_rows && strToken != NULL; i++ )
    {
        for ( int j = 0; j < 2 && strToken != NULL; j++ )
        {
            givenArr[i][j] = strtol( strToken, NULL, 10 );
            strToken = strtok( NULL, separator);
        }
    }

    free( outt );

    *nb_rows = i;
}

int main( void )
{
    char *input =
        " 2 1\n"
        " 3 2\n"
        " 5 2\n"
        " 5 4\n"
        " 6 1\n"
        " 6 2\n"
        " 7 1\n"
        " 7 3\n"
        " 7 4\n"
        " 8 1\n"
    ;

    int arr[10][2] = {0};
    int nb_rows = sizeof arr / sizeof *arr;
    arrayConstruction( &nb_rows, arr, input );

    for ( int i = 0; i < nb_rows; i++ )
    {
        printf( "%d---%d\n", arr[i][0], arr[i][1] );
    }
}

这个程序与另一个程序有相同的输出。

相关问题