01/10/2018, 08:20

Bị lỗi runtime khi xóa 1 cột trong ma trận (con trỏ cấp 2)

Continue discussion from Lỗi khi thêm 1 column vào trong ma trận

Như đã nói, e có đoạn code sau để thêm/xóa dòng/cột trong ma trận:

#include <stdio.h>
#include <stdlib.h>
#include <time.h>

void FillOut(int **, int, int); // File out matrix automatically
void Output(int **, int, int); // Show matrix on screen
void SwapRows(int *, int *, int); // Swap two rows
void ValueSwap(int *, int *); // Swap two values
void AddRows(int ***, int *, int, int *, int); // Insert a row in the matrix
void AddColumns(int ***, int, int *, int *, int); // Insert a column in the matrix
void DeleteRows(int ***, int *, int, int); // Delete a row in matrix
void DeleteColumns(int ***, int, int *, int); // Delete a column in matrix

void FillOut(int **arr, int rows, int columns)
{
    for (int i = 0; i < rows * columns; ++i) {
        *(*(arr + i / columns) + i % columns) = 1 + rand() % 100;
    }
}

void Output(int **arr, int rows, int columns)
{
    for (int i = 0; i < rows * columns; ++i) {
        printf("%5d", *(*(arr + i / columns) + i % columns));
        if ((i + 1) % columns == 0)
            printf("
");
    }
}

void SwapRows(int *arr1, int *arr2, int size)
{
    for (int i = 0; i < size; ++i) {
        int Temp = arr1[i];
        arr1[i] = arr2[i];
        arr2[i] = Temp;
    }
}

void ValueSwap(int *a, int *b)
{
    int Temp = *a;
    *a = *b;
    *b = Temp;
}

void AddRows(int ***arr, int *rows, int columns, int *insert_array, int rows_index)
{
    *arr = (int **)realloc(*arr, (*rows + 1) * sizeof(int *));
    (*arr)[*rows] = (int *)calloc(columns, sizeof(int));
    for (int i = 0; i < columns; ++i)
        *(*(*arr + *rows) + i) = *(insert_array + i);
    for (int i = *rows; i > rows_index; --i) {
        SwapRows((*arr)[i], (*arr)[i - 1], columns);
    }
    ++(*rows);
}

void AddColumns(int ***arr, int rows, int *columns, int *insert_array, int columns_index)
{
    for (int i = 0; i < rows; ++i) {
        (*arr)[i] = (int *)realloc((*arr)[i], (*columns + 1) * sizeof(int));
        (*arr)[i][*columns] = insert_array[i];
    }
    for (int i = 0; i < rows; ++i) {
        for (int j = *columns; j > columns_index; --j) {
            ValueSwap(&(*arr)[i][j], &(*arr)[i][j - 1]);
        }
    }
    ++(*columns);
}

void DeleteRows(int ***arr, int *rows, int columns, int rows_index)
{
    for (int i = rows_index; i < *rows - 1; ++i) {
        SwapRows((*arr)[i], (*arr)[i + 1], columns);
    }
    free((*arr)[--(*rows)]);
    *arr = (int **)realloc(*arr, *rows * sizeof(int *));
}

void DeleteColumns(int ***arr, int rows, int *columns, int columns_index)
{
    for (int i = 0; i < rows; ++i) {
        for (int j = columns_index; j < *columns - 1; ++j) {
            ValueSwap(&(*arr)[i][j], &(*arr)[i][j + 1]);
        }
        free((*arr)[i][*columns - 1]);
        (*arr)[i] = (int *)realloc((*arr)[i], (*columns - 1) * sizeof(int));
    }
    --(*columns);
}

int main()
{
    srand(time(NULL));
    int rows, columns;
    printf("Type the number of row and column: ");
    scanf("%d %d", &rows, &columns);
    // allocate 2D array (level 2-pointer)
    int **arr = (int **)calloc(rows, sizeof(int *));
    for (int i = 0; i < rows; ++i) {
        arr[i] = (int *)calloc(columns, sizeof(int));
    }
    printf("Current matrix:
");

    FillOut(arr, rows, columns);
    Output(arr, rows, columns);

    int *insert_array = (int *)calloc(columns, sizeof(int)); // This array contains "rows" integer elements to add to the matrix
    for (int i = 0; i < columns; ++i)
        *(insert_array + i) = 1 + rand() % 100;
    int rows_index; // Denoting the position of row to add
    // Checking if row index is not valid
    do {
        printf("Type the number of row's index: ");
        scanf("%d", &rows_index);
        if (rows_index > rows)
            printf("Row's index is invalid. Please check again!
");
    } while (rows_index > rows);

    AddRows(&arr, &rows, columns, insert_array, rows_index);
    printf("New matrix:
");
    Output(arr, rows, columns);

    int *insert_array2 = (int *)calloc(rows, sizeof(int)); // This array contains "columns" integer elements to add to the matrix
    for (int i = 0; i < rows; ++i) {
        *(insert_array2 + i) = 1 + rand() % 100;
    }
    int columns_index; // Denoting the position of column to add
    // Checking if column index is not valid
    do {
        printf("Type the number of column's index: ");
        scanf("%d", &columns_index);
        if (columns_index > columns)
            printf("Column'index is invalid. Please check again!
");
    } while (columns_index > columns);

    AddColumns(&arr, rows, &columns, insert_array2, columns_index);
    printf("New matrix:
");
    Output(arr, rows, columns);

    int rows_delete;
    do {
        printf("Type the number of row's index: ");
        scanf("%d", &rows_delete);
        if (rows_delete < 0 || rows_delete > rows - 1)
            printf("Row's index is invalid. Please check again!
");
    } while (rows_delete < 0 || rows_delete > rows - 1);
    DeleteRows(&arr, &rows, columns, rows_delete);
    printf("New matrix:
");
    Output(arr, rows, columns);

    int columns_delete;
    do {
        printf("Type the number of column's index: ");
        scanf("%d", &columns_delete);
        if (columns_delete < 0 || columns_delete > columns - 1)
            printf("Column's index is invalid. Please check again!
");
    } while (columns_delete < 0 || columns_delete > columns - 1);
    DeleteColumns(&arr, rows, &columns, columns_delete);
    printf("New matrix:
");
    Output(arr, rows, columns);
    // Free pointer
    free(insert_array);
    free(insert_array2);
    for (int i = 0; i < rows; ++i) {
        free(arr[i]);
    }
    free(arr);
    return 0;
}

Căn bản là trong source code trên, chỉ có hàm DeleteColumns dùng để xóa 1 cột ra khỏi ma trận bị lỗi runtime.
Nếu mình nhập số dòng và số cột ít thì hàm DeleteColumns vẫn xóa ok:

Nhưng nếu nhập số dòng và cột nhiều hơn tí thì bị lỗi runtime

Ai phát hiện ra lỗi chỉ giúp e với ạ, e cảm ơn nhiều

Tao Không Ngu. viết 10:33 ngày 01/10/2018

HI Long Dragon.
Bạn làm theo hướng dẫn nhé. Dảm bảo OK.

STDIO

Cơ Bản Debug Trong Visual Studio :: Bài viết :: STDIO

Hiện nay, hầu hết các IDE đều hỗ trợ khả năng gỡ rối (debug) chương trình bằng cách chạy từng dòng lệnh (step by step) và xem xét sự thay đổi giá trị của các biến. Bài viết này sẽ giúp các bạn làm quen với công cụ Debug trong Visual Studio.

Long Dragon viết 10:25 ngày 01/10/2018

Máy mình yếu nên ko thể dùng VS, còn CodeBlocks thì bị yếu ở trình debug nên mình ko thể phát hiện ra lỗi

Tao Không Ngu. viết 10:30 ngày 01/10/2018

HI Long Dragon.
Bạn làm theo hướng dẫn nhé. Dảm bảo OK.

Long Dragon viết 10:28 ngày 01/10/2018

Mình đã bảo trình debug của CB ko đầy đủ tools như VS nên ko phát hiện lỗi được mà

Tao Không Ngu. viết 10:30 ngày 01/10/2018

HI Long Dragon.
Bạn làm theo hướng dẫn nhé. Dảm bảo OK.
1 Mội trình debug đều có breakpoint.
2 Đều cho xem giá trị của các biến.
3 Đều cho sửa các giá trị đó.

Bạn đã dùng chưa vậy. Nếu chưa mình có thể hướng dẫn bạn.
1 Đặt break tại vị trí nghi ngờ cụ thể là dòng đầu của hàm DeleteColums

void DeleteColumns(int ***arr, int rows, int *columns, int columns_index)
{
//Thêm hàm printf để xác định chính xác.
printf("Dẻlete"); // Đặt break tại đây.
    for (int i = 0; i < rows; ++i) {
        for (int j = columns_index; j < *columns - 1; ++j) {
            ValueSwap(&(*arr)[i][j], &(*arr)[i][j + 1]);
        }
        free((*arr)[i][*columns - 1]);
        (*arr)[i] = (int *)realloc((*arr)[i], (*columns - 1) * sizeof(int));
    }
    --(*columns);
}

Bạn nói là khi gọi hàm bình thường không lỗi -> Kiểm tra giá trị được truyền vào hàm. Nếu OK cho chạy tiếp.
Nếu lỗi xem lại hàm gọi nó và kiểm tra các đối truyền vào được gán như thế nào.

Long Dragon viết 10:27 ngày 01/10/2018

Mấy cái nút debug mình biết hết mà, nhưng nó ko cung cấp giá trị của con trỏ cấp 1 (mảng 1 chiều) và con trỏ cấp 2 (mảng 2 chiều) cho mình trong cửa sổ watches, nên ko thể xem dc gì

Tao Không Ngu. viết 10:24 ngày 01/10/2018

HI Long Dragon.
In nó ra! @_@!

Tao Không Ngu. viết 10:31 ngày 01/10/2018

HI Long Dragon…
Chết tại hàm free

Bạn đang xóa cài gì vậy ?

Long Dragon viết 10:31 ngày 01/10/2018

Bạn đang xóa cài gì vậy ?

Thế à
À, em định là dồn cái phần tử ở cột của mỗi hàng cần xóa về cuối hàng rồi free cái phần tử ở cuối hàng đó luôn trước khi realloc => vì sao lỗi thế a ?

Tao Không Ngu. viết 10:27 ngày 01/10/2018

HI Long Dragon.
Có phải con trỏ không mà free.

Long Dragon viết 10:21 ngày 01/10/2018

Có phải con trỏ không mà free.

Ý chết, em nhầm
Thế mình chỉ realloc lại cái hàng đó thôi hả anh ?

Bài liên quan
0