Function that copies a 3d array in C?

蓝咒 提交于 2019-12-14 03:31:27

问题


Hi I stumbled upon a question in my textbook that states: 'Write a function that makes a copy of the contents of a 3D array of integers. The function should support any 3D array size.'

After discussing it with my lecturer he specified that the prototype of the function should look something similar to this (this is 2D, I need 3D).

int sum2d(int rows, int cols, int ar[rows][cols]);

Now how I currently coded it is by making everything in the main function and it works like it should, i.e copies all contents etc.

 int main()
    {
        int x,y,z;
        printf("Enter x value.\n");
        scanf("%d", &x);
        printf("Enter y value.\n");
        scanf("%d", &y);
        printf("Enter z value.\n");
        scanf("%d", &z);

        int *arrx = malloc(x * sizeof(*arrx));
        int *arry = malloc(y * sizeof(*arry));
        int *arrz = malloc(z * sizeof(*arrz));



        printf("The size of the array is %d.\n", x*y*z);
        /* 3D array declaration*/
        int disp[x][y][z];
        int cpydisp[x][y][z];


        /*Counter variables for the loop*/
        int i, j, k;
        for(i=0; i<x; i++) {
            for(j=0;j<y;j++) {
                for (k = 0; k < z; k++) {
                    printf("Enter value for disp[%d][%d][%d]:", i, j, k);
                    scanf("%d", &disp[i][j][k]);
                }
            }
        }

        memcpy(cpydisp,disp, sizeof(disp));

        //Displaying array elements
        printf("Three Dimensional array elements:\n");
        for(i=0; i<x; i++) {
            for(j=0;j<y;j++) {
                for (k = 0; k < z; k++) {
                    printf("%d ", cpydisp[i][j][k]);
                }
                printf("\n");
            }
        }
    }

However this is not correct since I need to implement a function just for copying and I came up with this. Create a function called void array_copy which practically copies the contents of the array disp to another array cpydisp by memcpy. The function array_copy is then called in the main however this is not working.

       int i, j, k;
        int x,y,z;
        int disp[x][y][z];
        int cpydisp[x][y][z];


void array_copy() {

        memcpy(cpydisp, disp, sizeof(disp));

    //Displaying array elements
        printf("Three Dimensional array elements:\n");
        for (i = 0; i < x; i++) {
            for (j = 0; j < y; j++) {
                for (k = 0; k < z; k++) {
                    printf("%d ", cpydisp[i][j][k]);
                }
                printf("\n");
            }
        }
    }

    int main()
    {
        printf("Enter x value.\n");
        scanf("%d", &x);
        printf("Enter y value.\n");
        scanf("%d", &y);
        printf("Enter z value.\n");
        scanf("%d", &z);

        //int *arrx = malloc(x * sizeof(*arrx));
        //int *arry = malloc(y * sizeof(*arry));
        //int *arrz = malloc(z * sizeof(*arrz));



        printf("The size of the array is %d.\n", x*y*z);
        /* 3D array declaration*/

        /*Counter variables for the loop*/
        int i, j, k;
        for(i=0; i<x; i++) {
            for(j=0;j<y;j++) {
                for (k = 0; k < z; k++) {
                    printf("Enter value for disp[%d][%d][%d]:", i, j, k);
                    scanf("%d", &disp[i][j][k]);
                }
            }
        }

        array_copy();

    }

Any thoughts please on how I can get it fixed, since I can't seem to understand what's wrong with it when it clearly can take any size by the user imputing the size he wants prior to having anything started.

Thanks in Advance

Edit:

#include<stdio.h>
#include <string.h>
int x,y,z;
int i, j, k;

void user_input(){

    printf("Enter x value.\n");
    scanf("%d", &x);
    printf("Enter y value.\n");
    scanf("%d", &y);
    printf("Enter z value.\n");
    scanf("%d", &z);
}


void array_copy() {

    int disp[x][y][z];
    int cpydisp[x][y][z];

    memcpy(cpydisp, disp, sizeof(disp));
    //Displaying array elements
    printf("Three Dimensional array elements:\n");
    for (i = 0; i < x; i++) {
        for (j = 0; j < y; j++) {
            for (k = 0; k < z; k++) {
                printf("%d ", cpydisp[i][j][k]);
            }
            printf("\n");
        }
    }
}


int main()
{
    user_input();
    int disp[x][y][z];
    int cpydisp[x][y][z];

    printf("The size of the array is %d.\n", x*y*z);
    /* 3D array declaration*/

    /*Counter variables for the loop*/
    for(i=0; i<x; i++) {
        for(j=0;j<y;j++) {
            for (k = 0; k < z; k++) {
                printf("Enter value for disp[%d][%d][%d]:", i, j, k);
                scanf("%d", &disp[i][j][k]);
            }
        }
    }

    array_copy();

}

I have retried it this way now something is being outputted rather than the second attempt however the output is just random numbers. i.e:

Enter x value.
1

Enter y value.
2

Enter z value.
3

The size of the array is 6.

Enter value for disp[0][0][0]:1
1
Enter value for disp[0][0][1]:2
2
Enter value for disp[0][0][2]:3
3
Enter value for disp[0][1][0]:4
4
Enter value for disp[0][1][1]:5
5
Enter value for disp[0][1][2]:6
6
Three Dimensional array elements:
797168 0 6421264
0 3 0

Process finished with exit code 0

The correct output should be 1,2,3,4,5,6

Thanks again


回答1:


Write a function that makes a copy of the contents of a 3D array of integers. The function should support any 3D array size

Something like

int sum2d(int rows, int cols, int ar[rows][cols]);

OP's approach of using a global variable-length array (VLA) fails as VLAs are not allowed at file scope.

VLAs cannot be initialized (given a value at declaration). However, their elements can be assigned at run-time.


With a VLA d[x][y][z] (available in C99 and optionally in C11), it is easy with memcpy().
Within a function, use size: sizeof d[0] * x.

memcpy(d, src, sizeof d[0] * x);

Implementation notes:

s, d are pointers.

size_t is some unsigned type that is the right width for handling size and array indexes. int may be too narrow.

With int d[x][y][z] as a parameter, the dimensional info x is lost.
x here may be used by the compiler for select optimizations and checks, but code sees d as type int (*)[y][z].

#include <stddef.h>

void copy3d(size_t x, size_t y, size_t z, int d[x][y][z], int src[x][y][z]) {
  printf("s[%zu][%zu][%zu]\nSizes: d:%zu, d[]:%zu, d[][]:%zu, d[][][]:%zu\n\n",
      x, y, z, sizeof d, sizeof d[0], sizeof d[0][0], sizeof d[0][0][0]);
  // 'sizeof' on array function parameter 'src' returns 
  //     size of 'int (*)[(sizetype)(y)][(sizetype)(z)]
  memcpy(d, src, sizeof d[0] * x);
}

Sample usage

#include <stdio.h>

int main(void) {
  size_t x = (unsigned) rand() % 4 + 1;
  size_t y = (unsigned) rand() % 4 + 1;
  size_t z = (unsigned) rand() % 4 + 1;
  int src[x][y][z];
  int i = 0;

  for (size_t xi = 0; xi < x; xi++) {
    for (size_t yi = 0; yi < y; yi++) {
      for (size_t zi = 0; zi < z; zi++) {
        src[xi][yi][zi] = ++i;
      }
    }
  }

  int dest[x][y][z];
  // Call with two 3D: dest, and src, along with dimension info.
  copy3d(x, y, z, dest, src);

  for (size_t xi = 0; xi < x; xi++) {
    printf("{");
    for (size_t yi = 0; yi < y; yi++) {
      printf("{");
      for (size_t zi = 0; zi < z; zi++) {
        printf("%2d ", dest[xi][yi][zi]);
      }
      printf("}, ");
    }
    printf("}\n");
  }
}

Output

s[2][4][3]
Sizes: d:8, d[]:48, d[][]:12, d[][][]:4

{{ 1  2  3 }, { 4  5  6 }, { 7  8  9 }, {10 11 12 }, }
{{13 14 15 }, {16 17 18 }, {19 20 21 }, {22 23 24 }, }



回答2:


Given that you have an actual 3D array, the function is simply:

memcpy( dst, src, sizeof(int[x][y][z]) ); 

If you want to write a less efficient version yourself, for learning purposes, then it goes like this:

void copy (size_t x, size_t y, size_t z, int dst[x][y][z], int src[x][y][z])
{
  for(size_t i=0; i<x; i++)
    for(size_t j=0; j<y; j++)
      for(size_t k=0; k<z; k++)
        dst[i][j][k] = src[i][j][k];
}

The reason why your code doesn't work is because you used variable-length arrays (VLA) but declared them at file scope ("global"), which isn't allowed. VLA must be declared at local scope, and the array bounds must be set to valid values before the VLA declaration.

The above code doesn't care how the 3D array is allocated, but leaves that to the caller.



来源:https://stackoverflow.com/questions/54127071/function-that-copies-a-3d-array-in-c

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!