This question already has an answer here:
Closed 11 months ago.
Dynamic memory access only works inside function
(1个答案)
我的代码有一些问题,问题是我没有真正得到SEG错误,我可以运行它,也可以得到良好的结果,但当我使用valgrind时,我得到一些内存泄漏错误,如:
问题是,我将main()中分配的两个矩阵(带有calloc)传递给名为meltdown()的函数。在这个函数中,我应该调整这两个列的大小,去掉第一列和最后一列。所以从一个5x5我应该得到一个3x3矩阵。我不知道如何使用realloc实现这一点,所以我使用另外两个矩阵将元素复制到其中,然后使初始矩阵指针指向这两个。。
实际上,我很沮丧,因为我的代码在实际问题上似乎工作得很好,并且很好地解决了问题,但是由于这个内存泄漏问题,我得了0分。
当您调用函数时,必须获取地址:
(1个答案)
我的代码有一些问题,问题是我没有真正得到SEG错误,我可以运行它,也可以得到良好的结果,但当我使用valgrind时,我得到一些内存泄漏错误,如:
==2265== Invalid read of size 4
==2265== at 0x109A3B: move (in /home/cosmi/Desktop/315CA_CojocaruCosmin_Tema3/snowfight)
==2265== by 0x10B419: main (in /home/cosmi/Desktop/315CA_CojocaruCosmin_Tema3/snowfight)
==2265== Address 0x55ccb88 is 8 bytes inside a block of size 20 free'd
==2265== at 0x4C30D3B: free (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2265== by 0x10A0F6: meltdown (in /home/cosmi/Desktop/315CA_CojocaruCosmin_Tema3/snowfight)
==2265== by 0x10B4A9: main (in /home/cosmi/Desktop/315CA_CojocaruCosmin_Tema3/snowfight)
==2265== Block was alloc'd at
==2265== at 0x4C31B25: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==2265== by 0x10AFE9: main (in /home/cosmi/Desktop/315CA_CojocaruCosmin_Tema3/snowfight)
问题是,我将main()中分配的两个矩阵(带有calloc)传递给名为meltdown()的函数。在这个函数中,我应该调整这两个列的大小,去掉第一列和最后一列。所以从一个5x5我应该得到一个3x3矩阵。我不知道如何使用realloc实现这一点,所以我使用另外两个矩阵将元素复制到其中,然后使初始矩阵指针指向这两个。。
int main() {
int **a = calloc((2 * R + 1) , sizeof(int*));
int **b = calloc((2 * R + 1) , sizeof(int*));
for (i = 0; i < (2 * R + 1); i++) {
a[i] = calloc((2 * R + 1) , sizeof(int));
b[i] = calloc((2 * R + 1) , sizeof(int));
}
}
void meltdown(int **a, int **b, int R, ..) {
int n = 2 * R + 1;
int **c = malloc((n - 2) * sizeof(int*));
for(i = 0; i < n - 2; i++)
c[i] = malloc((n-2)*sizeof(int));
l = 0;
for(i = 1; i < n - 1; i++) {
k = 0;
for(j = 1; j < n - 1; j++) {
c[l][k] = a[i][j];
k++;
}
l++;
}
for(i = 0; i < n; i++)
free(a[i]);
free(a);
a = c;
//same goes for b
}
实际上,我很沮丧,因为我的代码在实际问题上似乎工作得很好,并且很好地解决了问题,但是由于这个内存泄漏问题,我得了0分。
最佳答案
a = c
在内部分配局部变量,它不会影响调用方的变量。如果meltdown()
试图使用其main()
指针,它将访问由a
释放的内存,从而导致未定义的行为。
如果free(a);
应该更新调用者的变量,则需要传递一个指向该变量的指针,并在meltdown()
中取消对该变量的引用。
void meltdown(int ***aptr, int ***bptr, int R) {
int **a = *aptr;
int **b = *bptr;
int n = 2 * R + 1;
int **c = malloc((n - 2) * sizeof(int*));
for(i = 0; i < n - 2; i++)
c[i] = malloc((n-2)*sizeof(int));
l = 0;
for(i = 1; i < n - 1; i++) {
k = 0;
for(j = 1; j < n - 1; j++) {
c[l][k] = a[i][j];
k++;
}
l++;
}
for(i = 0; i < n; i++)
free(a[i]);
free(a);
*aptr = c;
//same goes for b
}
当您调用函数时,必须获取地址:
meltdown(&a, &b, R);
10-06 05:08