-1

I'm new to coding and new to C++. I am trying to write code in which one enters elements of the matrix. Afterwards, one column should be removed, and one row should be added. Removing one column works fine. However, after reallocating memory for the new number of rows, I get the message: segmentation fault (core dumped). I am using pointers to create and edit my matrix. Here is my code. Thanks for any help!

#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;
    }
fuentesj
  • 154
  • 7
Marina
  • 1
  • 2
  • 2
    use `std::vector` or `std::array`. Manual dynamic memory isnt really for beginners. Afer many years of C++ I still dont feel ready for it ;) – 463035818_is_not_an_ai Apr 05 '20 at 16:24
  • 3
    Well, the first problem is that the above code is not C++, but C code. If you'd really like to learn C++, you need to [start with a good C++ book](https://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). – Sam Varshavchik Apr 05 '20 at 16:24
  • Welcome to Stack Overflow! It sounds like you may need to learn how to use a [debugger](https://en.wikipedia.org/wiki/Debugger) to step through your code. With a good debugger, you can execute your program line by line and see where it is deviating from what you expect. This is an essential tool if you are going to do any programming. Further reading: [How to debug small programs](https://ericlippert.com/2014/03/05/how-to-debug-small-programs/). – Paul R Apr 05 '20 at 16:25
  • Don't do manual memory management in modern C++. *Especially* if you are new. Use containers and smart pointers. *Not* `new`/`delete` and *certainly not* `malloc`/`calloc`/`realloc`/`free` in C++ - just strike those from your memory, forget they exist - C++ is *not* C. – Jesper Juhl Apr 05 '20 at 16:25
  • 1
    @PaulR you should add [What is a debugger and how can it help me diagnose problems?](https://stackoverflow.com/q/25385173/5910058) to that. – Jesper Juhl Apr 05 '20 at 16:31
  • When you shift the rows, you want to count downwards, so te update part of your loop should be `i--` istead of `i++`. – M Oehm Apr 05 '20 at 16:58

2 Answers2

1

When you realloc memory for p, you add one new row to that array (one additional pointer). But you never allocate the memory for that new row, and eventually you access this uninitialized pointer.

But that's not the real problem. In the loop where you want to bump the pointers up to make space for the inserted row, your initial value and loop increment are both wrong. With an initial value of int i=r+1, the first write to *(p+i) will access one past the allocated space (which would be p[0] thru p[r]). The loop increment should be a decrement, --i. Once this loop is done, then you can allocate space for the new row.

1201ProgramAlarm
  • 32,384
  • 7
  • 42
  • 56
  • Thanks, I missed that tiny decrement thing :) When I fixed it, I got a different problem, which was due to the fact that two row pointers,after exiting the loop, were pointing to the same thing, and then I ended up having two identical rows (identical to the inserted row). I fixed it by changing that part of the code like this, and I also allocated memory for the additional row, and now it works! – Marina Apr 06 '20 at 17:24
  • p=(int**)realloc(p,(r+1)*sizeof(int*)); if(p==NULL) printf("Memory not allocated.\n"); else{ *(p+r)=(int*)calloc(c-1,sizeof(int)); for(int i=r;i>row-1;i--){ for(int j=0;j<=c-2;j++) *(*(p+i)+j)=*(*(p+i-1)+j); } – Marina Apr 06 '20 at 17:24
0

As other people here have stated, it is definitely easier to do this using std::vector.

However, I assume you are doing this as a learning exercise so I would definitely recommend you to finish this and understand where you went wrong. You were close, it looks like you just got confused with your indices. Try using more descriptive variable names and splitting stuff into functions to make it harder to get lost in your own code.

I modified your code to get it to do what i think you were trying to do. Take a look and let me know if that was helpful.

But yes, if you do any future C++ work, avoid doing C style malloc, alloc, free, etc... and consider working with the std libs.

#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;
}
teepers
  • 22
  • 4
  • 1
    It would be nice if you could indicate where you made changes to the code. For what it's worth, the last prompt says "Which row do you want to replace?", but I guess the code should insert a new row, otherwise the reallocation doesn't make sense. But perhaps the Marina can clarify. – M Oehm Apr 05 '20 at 17:15