动态数组的 C memcpy 行为
C memcpy behaviour with dynamic array
请注意在 memcpy
之后,我正在更改源矩阵中的值。它们会在目的地自动被替换。此外,当我更改目标数组值时,它们会转到源数组。为什么会这样?
有趣的是,即使在通过 free
命令删除了目标数组之后,值仍然是源数组。请让我知道这一点。提前致谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double *** double3d(long int dim1,long int dim2,long int dim3)
{
long int i,j,k;
double ***array;
array=(double ***)malloc(dim1*sizeof(double **));
for(i=0;i<dim1;i++)
{
array[i]=(double **)malloc(dim2*sizeof(double *));
for(j=0;j<dim2;j++)
array[i][j]=(double *)malloc(dim3*sizeof(double ));
}
return array;
}// end double3d
void summ(double ***A,double ***B, double ****C)
{
int i ,j ,k;
for(i=0;i<10;i++)
for(j=0;j<5;j++)
for(k=0;k<5;k++)
(*C)[i][j][k] = A[i][j][k] + B[i][j][k];
}
void main()
{
int i,j,k,nx,ny;
double ***M1, ***M2, ***M3, ***M4,***M5,***M6;
nx=5;ny=5;
M1=double3d(10,nx,ny);
M2=double3d(10,nx,ny);
M3=double3d(10,nx,ny);
M4=double3d(5,nx,ny);
M5=double3d(5,nx,ny);
M6=(double ***)malloc(10*sizeof(double **));
for(i=0;i<10;i++)
{
for(j=0;j<nx;j++)
for(k=0;k<ny;k++)
{
M1[i][j][k]=i;
M2[i][j][k]=1;
}
}
// Note random values are in M4 and M5 as they are not initalised
memcpy(M6, M4, 5 * sizeof(double **));
memcpy(M6+5, M5, 5 * sizeof(double **));
for(i=0;i<5;i++)
{
for(j=0;j<nx;j++)
for(k=0;k<ny;k++)
{
M4[i][j][k]=200;
M5[i][j][k]=700;
}
}
printf(" printing M6 Memcpy before addition\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%f ",M6[4][j][k]);
printf("\n");
for(k=0;k<ny;k++)
printf("%f ",M6[9][j][k]);
printf("\n");
}
// calling for non memcpy array
summ(M1,M2,&M3); printf(" Non memcpy output last value : %f \n",M3[9][nx-1][ny-1]);
// calling for memcpy
summ(M1,M2,&M6); printf(" memcpy output last value : %f \n",M6[9][nx-1][ny-1]);
printf(" printing M6 Memcpy for two sets after addtion\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%f ",M6[4][j][k]);
printf("\n");
}
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%f ",M6[9][j][k]);
printf("\n");
}
free(M6);// cleared M6
printf(" printing M4 Memcpy after deleting M6\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%.1f ,%.1f ,%.1f ,%.1f ,%.1f ",M4[0][j][k],M4[1][j][k],M4[2][j][k],M4[3][j][k],M4[4][j][k]);
printf("\n");
}
printf(" printing M5 Memcpy after deleting M6\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%.1f ,%.1f ,%.1f ,%.1f ,%.1f ",M5[0][j][k],M5[1][j][k],M5[2][j][k],M5[3][j][k],M5[4][j][k]);
printf("\n");
}
}
这里的"problem"是你(显然)误解了memcpy
的作用。
有
memcpy(M6, M4, 5 * sizeof(double **));
你基本上在做的是
M6[0] = M4[0];
M6[1] = M4[1];
// etc...
即您正在复制 指针 而不是它们指向的内容。
当调用 free(M6)
时,您只释放 M6
指向的内存。但是例如指向的数据M6[0]
和 M4[0]
仍然存在,并且仍然被 M4[0]
指向。
请注意在 memcpy
之后,我正在更改源矩阵中的值。它们会在目的地自动被替换。此外,当我更改目标数组值时,它们会转到源数组。为什么会这样?
有趣的是,即使在通过 free
命令删除了目标数组之后,值仍然是源数组。请让我知道这一点。提前致谢。
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
double *** double3d(long int dim1,long int dim2,long int dim3)
{
long int i,j,k;
double ***array;
array=(double ***)malloc(dim1*sizeof(double **));
for(i=0;i<dim1;i++)
{
array[i]=(double **)malloc(dim2*sizeof(double *));
for(j=0;j<dim2;j++)
array[i][j]=(double *)malloc(dim3*sizeof(double ));
}
return array;
}// end double3d
void summ(double ***A,double ***B, double ****C)
{
int i ,j ,k;
for(i=0;i<10;i++)
for(j=0;j<5;j++)
for(k=0;k<5;k++)
(*C)[i][j][k] = A[i][j][k] + B[i][j][k];
}
void main()
{
int i,j,k,nx,ny;
double ***M1, ***M2, ***M3, ***M4,***M5,***M6;
nx=5;ny=5;
M1=double3d(10,nx,ny);
M2=double3d(10,nx,ny);
M3=double3d(10,nx,ny);
M4=double3d(5,nx,ny);
M5=double3d(5,nx,ny);
M6=(double ***)malloc(10*sizeof(double **));
for(i=0;i<10;i++)
{
for(j=0;j<nx;j++)
for(k=0;k<ny;k++)
{
M1[i][j][k]=i;
M2[i][j][k]=1;
}
}
// Note random values are in M4 and M5 as they are not initalised
memcpy(M6, M4, 5 * sizeof(double **));
memcpy(M6+5, M5, 5 * sizeof(double **));
for(i=0;i<5;i++)
{
for(j=0;j<nx;j++)
for(k=0;k<ny;k++)
{
M4[i][j][k]=200;
M5[i][j][k]=700;
}
}
printf(" printing M6 Memcpy before addition\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%f ",M6[4][j][k]);
printf("\n");
for(k=0;k<ny;k++)
printf("%f ",M6[9][j][k]);
printf("\n");
}
// calling for non memcpy array
summ(M1,M2,&M3); printf(" Non memcpy output last value : %f \n",M3[9][nx-1][ny-1]);
// calling for memcpy
summ(M1,M2,&M6); printf(" memcpy output last value : %f \n",M6[9][nx-1][ny-1]);
printf(" printing M6 Memcpy for two sets after addtion\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%f ",M6[4][j][k]);
printf("\n");
}
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%f ",M6[9][j][k]);
printf("\n");
}
free(M6);// cleared M6
printf(" printing M4 Memcpy after deleting M6\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%.1f ,%.1f ,%.1f ,%.1f ,%.1f ",M4[0][j][k],M4[1][j][k],M4[2][j][k],M4[3][j][k],M4[4][j][k]);
printf("\n");
}
printf(" printing M5 Memcpy after deleting M6\n");
for(j=0;j<nx;j++)
{
for(k=0;k<ny;k++)
printf("%.1f ,%.1f ,%.1f ,%.1f ,%.1f ",M5[0][j][k],M5[1][j][k],M5[2][j][k],M5[3][j][k],M5[4][j][k]);
printf("\n");
}
}
这里的"problem"是你(显然)误解了memcpy
的作用。
有
memcpy(M6, M4, 5 * sizeof(double **));
你基本上在做的是
M6[0] = M4[0];
M6[1] = M4[1];
// etc...
即您正在复制 指针 而不是它们指向的内容。
当调用 free(M6)
时,您只释放 M6
指向的内存。但是例如指向的数据M6[0]
和 M4[0]
仍然存在,并且仍然被 M4[0]
指向。