首页 > 解决方案 > 更改读取输入大小时的内存泄漏

问题描述

我的 headtail 应用程序面临着非常奇怪的问题。当我尝试使用 Powershell(命令:Get-Content data.txt | .\Headtail.exe head 10)从文件 data.txt 中读取时,我总是得到正确且预期的输出。但是,如果我将输入从 data.txt 更改为 fail.txt,我将不会从输出函数(称为vypis())获得任何输出。

有谁知道这里发生了什么?

好的案例:命令输出(假设此输出与使用fail.txt作为输入相同(意味着应打印给定输入的内容))Get-Content data.txt | .\Headtail.exe head 10在 PowerShell 中

aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.

错误案例: Get-Content fail.txt命令的输出| .\Headtail.exe head 10在 PowerShell 中

/*NOTHING */

我的 headtail 函数的代码如下:

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

int const size = 15;
int last_changed = 0;

typedef struct {
    char **field;
    int *columns;
    int rows;
} TMatrix;

void set_size(TMatrix* matrix) {
    for (int i = 0; i < matrix->rows; i++) matrix->columns[i] = size;
}

TMatrix* allocate() {
    TMatrix* matrix = malloc(sizeof(TMatrix));
    if (!matrix) return NULL;

    matrix->field = malloc(size * sizeof(char*));
    if (!matrix->field) return NULL;

    matrix->rows = size;

    matrix->columns = malloc(size * sizeof(int));
    if (!matrix->field) return NULL;
    set_size(matrix);

    for (int i = 0; i < matrix->rows; i++) {
        matrix->field[i] = malloc(size * sizeof(char));
        if (!matrix->field[i]) return NULL;
    }

    return matrix;
}

void release(TMatrix* matrix) {
    for(int i = 0; i < matrix->rows; i++) free(matrix->field[i]);
    free(matrix->field);
    free(matrix->columns);
    free(matrix);
}

bool add_rows(TMatrix* matrix) {
    matrix->rows += 10;

    char** rebuf = realloc(matrix->field, matrix->rows * sizeof(char*));
    if (!rebuf) {
        free(rebuf);
        return false;
    }
    matrix->field = rebuf;

    int* rebufl = realloc(matrix->columns, matrix->rows * sizeof(int));
    if (!rebufl) {
        free(rebufl);
        return false;
    }
    matrix->columns = rebufl;

    for (int i = 1; i <= 10; i++) {
        char* rebuh = realloc(matrix->field[matrix->rows - i], size * sizeof(char));
        if (!rebuh) {
            free(rebuh);
            return false;
        }
        matrix->field[matrix->rows - i] = rebuh;
        matrix->columns[matrix->rows - i] = size;
    }

    return true;
}

bool add_column(TMatrix* matrix, int row) {
    matrix->columns[row] += 15;

    char* rebuf = realloc(matrix->field[row], matrix->columns[row] * sizeof(char));
    if (!rebuf) {
        free(rebuf);
        return false;
    }
    matrix->field[row] = rebuf;

    return true;
}

TMatrix* load(FILE* in) {
    char c;
    int actual_row = 0, actual_column = 0;

    TMatrix* matrix;
    if (!(matrix = allocate())) return NULL;

    while ((fscanf(in, "%c", &c)) != EOF) {
        matrix->field[actual_row][actual_column] = c;

        if (c != '\n') {
            actual_column += 1;
            if (((matrix->columns[actual_row]) - 1) == actual_column) {
                if (!add_column(matrix, actual_row)) return NULL;
            }
        }
        else if (c == '\n') {
            actual_column +=1;
            if (((matrix->columns[actual_row]) - 1) == actual_column) {
                if (!add_column(matrix, actual_row)) return NULL;
            }
            matrix->field[actual_row][actual_column] = '\0';
            actual_column = 0;
            actual_row += 1;
            last_changed += 1;
            if (((matrix->rows) - 1) == actual_row) {
                if (!add_rows(matrix)) return NULL;
            }
        }
    }

    return matrix;
}

bool output(FILE* out, TMatrix *matrix, double num_of_output_lines, char method[]) {
    if (!matrix) return false;
    if (num_of_output_lines <= 0) return false;
    if (matrix->rows <= 0) return false;
    if (num_of_output_lines > last_changed) return false;

    if (strcmp("head", method) == 0) {
        for (int i = 0; i < num_of_output_lines; i++) {
            for (int j = 0; j < matrix->columns[i]; j++) {
                if (matrix->field[i][j] != '\0') fprintf(out, "%c", matrix->field[i][j]);
                else break;
            }
        }
    }
    else if (strcmp("tail", method) == 0) {
        for (int a = (last_changed-1); a >= (last_changed - num_of_output_lines); a--) {
            for (int b = 0; b < matrix->columns[a]; b++) {
                if (matrix->field[a][b] != '\0') fprintf(out, "%c", matrix->field[a][b]);
                else break;
            }
        }
    }
    else return false;

    return true;
}

void Help() {
    fprintf(stdout, "-------------------------------------------------------------------------------------\n");
    fprintf(stdout, "* Help function - nothing important *\n");
    fprintf(stdout, "-------------------------------------------------------------------------------------\n");
}

int main(int argc, char *argv[])
{
   if (argc < 3 || argc > 4) {
        printf("!Valid count of arguments entered! \n");
        return -1;
    }

    if (strcmp("-h", argv[1]) == 0) Help();
    double num_of_output_lines = atoi(argv[argc - 1]);

    TMatrix* matrix = load(stdin);
    if (!matrix) {
        printf("!Error while loading! \n");
        return -1;
    }

    if (!output(stdout, matrix, num_of_output_lines, argv[argc - 2])) {
        printf("!Error while printing! \n");
        return -1;
    }

    release(matrix);
    return 0;
}

和 data.txt 的内容(工作正常,只是一个示例输入):

aaaaaaaaaaaaaaaaaaaaaaaaaaaa.
bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb.
ccccccccccccccccccccc.
dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.

最后是 fail.txt 的内容(没有得到任何输出,区别只是一些行的长度):

aaaaa.
bbbbbbb.
cccc.
ddddddd.
eeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee.
ffffffffffffffffffffffffffffffffffffffffffffffffffff.
ggggggggggggggggggggggggggggggggg.
hhhhh.
iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii.
jjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjjj.
kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk.
lllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllllll.
mmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmmm.
nnnnnnnnnnnnnnnnnnnnnnnnn.
ooooooooooo.
ppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppppp.
qqqqqqqqqqqqqqqqqqqqqqqqqqqqqq.
rrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrrr.
sssssssssssssssssssssssssssssssssssssssssssssssssssssssssssss.
ttttttttttttttttttttt.
uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu.
vvvvvvvvvvvvvvvvvvvvvvvvvvv.
wwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwwww.
xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx.
yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy.
zzzzzzzzzzzzzzzzzzzzzz.

标签: cmemorymemory-leaksmallocrealloc

解决方案


推荐阅读