Ошибка сегментации (дамп ядра) ошибка в динамическом c распределении памяти - PullRequest
0 голосов
/ 05 апреля 2020

Я новичок в кодировании и новичок в C ++. Я пытаюсь написать код, в который вводятся элементы матрицы. После этого необходимо удалить один столбец и добавить одну строку. Удаление одного столбца работает нормально. Однако после перераспределения памяти для нового числа строк я получаю сообщение: ошибка сегментации (ядро сброшено). Я использую указатели для создания и редактирования моей матрицы. Вот мой код Спасибо за любую помощь!

#include <stdio.h>
#include <stdlib.h>
int main()
{
int c,r,**p,column,row;
printf("Enter the number of rows and columns:\n");
scanf("%d\n%d",&r,&c);
p=(int**)calloc(r,sizeof(int*));
if(p==NULL) printf("Memory not allocated.\n");
else{
    for(int i=0;i<r;i++){
        *(p+i)=(int*)calloc(c,sizeof(int));
        printf("Enter %d. row\n",i+1);
        for(int j=0;j<c;j++){
            scanf("%d",*(p+i)+j);
        }
    }
    printf("Original matrix:\n");
    for(int i=0;i<r;i++){
        for(int j=0;j<c;j++){
            printf("%d ",*(*(p+i)+j));
        }
        printf("\n");
    }

    printf("Which column do you want to remove?");
    scanf("%d",&column);
    while(column<1||column>c){
        printf("Wrong entry, enter again:");
        scanf("%d",&column);
    }
    for(int i=0;i<=r-1;i++){
        for(int j=column-1;j<=c-2;j++)
            *(*(p+i)+j)=*(*(p+i)+j+1);
        *(p+i)=(int*)realloc(*(p+i),(c-1)*sizeof(int));
    }
    printf("Matrix without %d. column:\n",column);
    for(int i=0;i<r;i++){
        for(int j=0;j<c-1;j++)
            printf("%d ",*(*(p+i)+j));
        printf("\n");
    }
    printf("Which row do you want to replace?\n");
    scanf("%d",&row);
    while(row<1||row>r){
        printf("Wrong entry, enter again:\n");
        scanf("%d",&row);
    }
    p=(int**)realloc(p,(r+1)*sizeof(int*));
    if(p==NULL)
        printf("Memory not allocated.\n");
    else{
        printf("Enter %d. row",row);
        for(int i=r+1;i>row-1;i++){
            *(p+i)=*(p+i-1);
        }
        for(int j=0;j<c-2;j++)
            scanf("%d",*(p+row-1)+j);
        printf("New matrix:\n");
        for(int i=0;i<=r;i++){
            for(int j=0;j<c-2;j++)
                printf("%d ",*(*(p+i)+j));
            printf("\n");
        }
    }
    }
    return 0;
    }

Ответы [ 2 ]

1 голос
/ 05 апреля 2020

Когда вы реально c памяти для p, вы добавляете одну новую строку в этот массив (один дополнительный указатель). Но вы никогда не выделяете память для этой новой строки и в конечном итоге получаете доступ к этому неинициализированному указателю.

Но это не настоящая проблема. В l oop, где вы хотите увеличить указатели, чтобы освободить место для вставленной строки, ваше начальное значение и приращение l oop неверны. При начальном значении int i=r+1 первая запись в *(p+i) будет обращаться к одному после выделенного пространства (которое будет p[0] через p[r]). Приращение l oop должно быть уменьшением, --i. Как только это l oop сделано, вы можете выделить место для новой строки.

0 голосов
/ 05 апреля 2020

Как уже говорили другие люди, это определенно проще сделать с помощью std :: vector.

Однако я предполагаю, что вы делаете это как учебное упражнение, поэтому я определенно рекомендую вам закончить sh это и пойми, где ты ошибся. Вы были близки, похоже, вы просто запутались со своими показателями. Попробуйте использовать более описательные имена переменных и разбивать их на функции, чтобы было труднее потеряться в вашем собственном коде.

Я изменил ваш код, чтобы он делал то, что, как я думаю, вы пытались сделать. Посмотрите и дайте мне знать, если это было полезно.

Но да, если вы будете работать с C ++ в будущем, не выполняйте mallo c в стиле *1011*, allo c, free, et c ... и подумайте о работе с библиотеками std.

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

int main()
{
    int c, r, ** p, column, row;
    printf("Enter the number of rows and columns:\n");
    scanf_s("%d\n%d", &r, &c);
    p = (int**)calloc(r, sizeof(int*));
    if (p == NULL) printf("Memory not allocated.\n");
    else {
        for (int i = 0; i < r; i++) {
            *(p + i) = (int*)calloc(c, sizeof(int));
            printf("Enter %d. row\n", i + 1);
            for (int j = 0; j < c; j++) {
                scanf_s("%d", *(p + i) + j);
            }
        }
        printf("Original matrix:\n");
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++) {
                printf("%d ", *(*(p + i) + j));
            }
            printf("\n");
        }

        printf("Which column do you want to remove?");
        scanf_s("%d", &column);
        while (column<1 || column>c) {
            printf("Wrong entry, enter again:");
            scanf_s("%d", &column);
        }
        for (int i = 0; i <= r - 1; i++) {
            for (int j = column - 1; j <= c - 2; j++)
                * (*(p + i) + j) = *(*(p + i) + j + 1);
            *(p + i) = (int*)realloc(*(p + i), (c - 1) * sizeof(int));
        }
        c -= 1;
        printf("Matrix without %d. column:\n", column);
        for (int i = 0; i < r; i++) {
            for (int j = 0; j < c; j++)
                printf("%d ", *(*(p + i) + j));
            printf("\n");
        }
        printf("Which row do you want to replace?\n");
        scanf_s("%d", &row);
        while (row<1 || row>r) {
            printf("Wrong entry, enter again:\n");
            scanf_s("%d", &row);
        }
        p = (int**)realloc(p, (r + 1) * sizeof(int*));
        if (p == NULL)
            printf("Memory not allocated.\n");
        else {
            printf("Enter %d. row", row);
            for (int i = 0; i < c; i++)
                scanf_s("%d", *(p + row -1) + i);
            printf("New matrix:\n");
            for (int i = 0; i < r; i++) {
                for (int j = 0; j < c; j++)
                    printf("%d ", *(*(p + i) + j));
                printf("\n");
            }
        }
    }
    return 0;
}
...