【发布时间】:2016-11-18 23:35:32
【问题描述】:
所以我正在编写一个读取矩阵的代码,然后对它们进行一些计数。
我分配内存来存储矩阵并用更多分配的 数组 填充它并最终释放所有内容,但 Valgrind 告诉我,当我分配内存时我有内存泄漏,然后不要' t 释放它但是当我释放它时,程序不起作用,我得到 SIGSEGV。如下:
int main() {
int ***arrMatrices= (int***) calloc(100, sizeof(int**));
char *operations = (char*) calloc(100, sizeof(char));
int heights[100], widths[100];
int noOfMatrices= 0, output = 0;
...
output = readMatrix(arrMatrices, &noOfMatrices, heights, widths);
...
freeEverything(arrMatrices,noOfMatrices,heights,widths,operations);
return (0);
}
int readMatrix(int ***arrMatrices, int *noOfMatrices, int *heights, int *widths){
int height, width;
int output = scanf("%d %d",&height, &width);
int result = 1;
...
int **matrix = (int**) calloc(height, sizeof(int*));
for(int i = 0; i < height; i++){
int *row = (int*) calloc(width, sizeof(int));
for(int y = 0; y < width; y++){
output = scanf("%d",(row+y));
if(output < 1) result = -1;
}
matrix[i] = row;
}
arrMatrices[*noOfMatrices] = matrix;
heights[*noOfMatrices] = height;
widths[*noOfMatrices] = width;
*noOfMatrices+=1;
return result;
}
void freeEverything(int ***arrMatrices, int noOfMatrices, int *heights, int *widths, char *operations){
for(int i = 0; i < noOfMatrices; i++){
for(int row = 0; row < heights[i]; row++){
free(arrMatrices[i][row]);
}
printf("%d\n",i);
free(arrMatrices[i]);
}
free(arrMatrices);
free(operations);
}
所以事情是我读取矩阵,将其加载到我的数组中并返回。如果我尝试释放它,我会得到一个错误,并且显然最终释放它 - 逐行和逐矩阵跟随我的整个数组 - 是不够的。 Valgrind 明确表示是readMatrix 中的矩阵alloc。
谁能告诉我正确的做法?
编辑(根据建议添加代码+编辑):
这是我的代码的另一个 sn-p - 以下函数将矩阵相乘。在那里我以相同的方式声明矩阵,但没有内存泄漏。
int multiply(int ***arrOfMatrices, int firstIndex, int secondIndex, int *heights, int *widths){
if(widths[firstIndex] != heights[secondIndex]) return -1;
int **matrix = (int**) calloc(heights[firstIndex],sizeof(int*));
for(int i = 0; i < heights[firstIndex]; i++){
int *row = (int*) calloc(widths[secondIndex], sizeof(int));
for(int y = 0; y < widths[secondIndex]; y++){
int sum = 0;
for(int j = 0; j < widths[firstIndex]; j++){
sum = sum + (arrOfMatrices[firstIndex][i][j] * arrOfMatrices[secondIndex][j][y]);
}
row[y] = sum;
}
matrix[i] = row;
}
arrOfMatrices[secondIndex] = matrix;
heights[secondIndex] = heights[firstIndex];
return 1;
}
EDIT 2(发布整个代码):
#include <stdio.h>
#include <stdlib.h>
void printMatrix(int ***arrOfMatrices, int index, int *heights, int *widths){
int height = heights[index];
int width = widths[index];
printf("%d %d\n",height, width);
for(int i = 0; i < height; i++){
printf("%d",arrOfMatrices[index][i][0]);
for(int y = 1; y < width; y++){
printf(" %d",arrOfMatrices[index][i][y]);
}
printf("\n");
}
}
int readMatrix(int ***arrOfMatrices, int *noOfMatrices, int *heights, int *widths){
int height, width;
int output = scanf("%d %d",&height, &width);
int result = 1;
if(output < 2){
fprintf(stderr,"Error\n"); return 100;
}
int **matrix = (int**) calloc(height, sizeof(int*));
for(int i = 0; i < height; i++){
int *row = (int*) calloc(width, sizeof(int));
for(int y = 0; y < width; y++){
output = scanf("%d",(row+y));
if(output < 1) result = -1;
}
matrix[i] = row;
}
if(result == -1){
for(int i = 0; i < height; i++){
free(matrix[i]);
}
free(matrix);
return result;
}
arrOfMatrices[*noOfMatrices] = matrix;
heights[*noOfMatrices] = height;
widths[*noOfMatrices] = width;
*noOfMatrices+=1;
return result;
}
int multiply(int ***arrOfMatrices, int firstIndex, int secondIndex, int *heights, int *widths){
if(widths[firstIndex] != heights[secondIndex]) return -1;
int **matrix = (int**) calloc(heights[firstIndex],sizeof(int*));
for(int i = 0; i < heights[firstIndex]; i++){
int *row = (int*) calloc(widths[secondIndex], sizeof(int));
for(int y = 0; y < widths[secondIndex]; y++){
int sum = 0;
for(int j = 0; j < widths[firstIndex]; j++){
sum = sum + (arrOfMatrices[firstIndex][i][j] * arrOfMatrices[secondIndex][j][y]);
}
row[y] = sum;
}
matrix[i] = row;
}
arrOfMatrices[secondIndex] = matrix;
heights[secondIndex] = heights[firstIndex];
//free(matrix);
return 1;
}
int addSubstract(int ***arrOfMatrices, int firstIndex, int secondIndex, int *heights, int *widths, int modificator){
if(heights[firstIndex] != heights[secondIndex] || widths[firstIndex] != widths[secondIndex]) return -1;
for(int i = 0; i < heights[firstIndex]; i++){
for(int y = 0; y < widths[secondIndex]; y++){
arrOfMatrices[secondIndex][i][y] = (modificator * arrOfMatrices[secondIndex][i][y]) + arrOfMatrices[firstIndex][i][y];
}
}
return 1;
}
int countPriorityOperations(int ***arrOfMatrices, char *operations, int noOfMatrices, int *heights, int *widths){
/*
Picks all multiplications and counts 'em first
*/
int output;
for(int i = 0; i < noOfMatrices-1;i++){
if(operations[i] == '*'){
output = multiply(arrOfMatrices,i,i+1,heights,widths);
if(output == -1) return -1;
}
}
return 1;
}
int countRemainingOperations(int ***arrOfMatrices, char *operations, int noOfMatrices, int *heights, int *widths){
/*
Does all the other operations that aren't of the multiply masterrace
Skips matrices that have already been multiplied
*/
for(int i = 0; i < noOfMatrices-1;i++){
if(operations[i] == '*') continue;
if(operations[i] == '+' || operations[i] == '-'){
int modificator = 0;
if(operations[i] == '+') modificator = 1; else modificator = -1;
if(operations[i+1] != '*'){
if(addSubstract(arrOfMatrices,i, i+1, heights, widths, modificator) == -1) return -1;
}else{
if(addSubstract(arrOfMatrices,i, i+2, heights, widths, modificator) == -1) return -1;
++i;
}
}
}
return 1;
}
void freeEverything(int ***arrOfMatrices, int noOfMatrices, int *heights, int *widths, char *operations){
for(int i = 0; i < noOfMatrices; i++){
for(int row = 0; row < heights[i]; row++){
free(arrOfMatrices[i][row]);
}
free(arrOfMatrices[i]);
}
free(arrOfMatrices);
free(operations);
}
int main() {
int ***arrOfMatrices = (int***) calloc(100, sizeof(int**));
char *operations = (char*) calloc(100, sizeof(char));
int heights[100], widths[100];
int noOfMatrices = 0, output = 0;
while(output != EOF){
output = readMatrix(arrOfMatrices, &noOfMatrices, heights, widths);
if(output == -1){
fprintf(stderr,"Error\n"); return 100;
}
char temp;
output = scanf(" %c",&temp);
if(temp != '+' && temp != '-' && temp != '*' && output != EOF){
fprintf(stderr,"Error\n"); return 100;
}
if(output == EOF) break;
operations[noOfMatrices-1] = temp;
}
if(countPriorityOperations(arrOfMatrices,operations,noOfMatrices, heights, widths) == -1){
fprintf(stderr,"Error\n"); return 100;
}
if(countRemainingOperations(arrOfMatrices,operations,noOfMatrices, heights, widths) == -1){
fprintf(stderr,"Error\n"); return 100;
}
printMatrix(arrOfMatrices,noOfMatrices-1,heights,widths);
freeEverything(arrOfMatrices,noOfMatrices,heights,widths,operations);
return (0);
}
所有输入正确且程序正确完成时的Valgrind输出:
==24== HEAP SUMMARY:
==24== in use at exit: 72 bytes in 4 blocks
==24== total heap usage: 21 allocs, 17 frees, 1,244 bytes allocated
==24==
==24== 72 (24 direct, 48 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 2
==24== at 0x4C2C9B4: calloc (vg_replace_malloc.c:711)
==24== by 0x400896: readMatrix (in [path])
==24== by 0x40109C: main (in [path])
==24==
==24== LEAK SUMMARY:
==24== definitely lost: 24 bytes in 1 blocks
==24== indirectly lost: 48 bytes in 3 blocks
==24== possibly lost: 0 bytes in 0 blocks
==24== still reachable: 0 bytes in 0 blocks
==24== suppressed: 0 bytes in 0 blocks
==24==
==24== For counts of detected and suppressed errors, rerun with: -v
==24== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)
【问题讨论】:
-
大声笑我发现了错误
-
让我把它放到答案中
标签: c matrix memory-management memory-leaks valgrind