【问题标题】:Segmentation fault (core dumped) error in dynamic memory allocation动态内存分配中的分段错误(核心转储)错误
【发布时间】:2020-07-17 14:49:00
【问题描述】:

我是编码新手,也是 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;
    }

【问题讨论】:

  • 使用std::vectorstd::array。手动动态内存真的不适合初学者。经过多年的 C++,我仍然没有为它做好准备;)
  • 嗯,第一个问题就是上面的代码不是C++,而是C代码。如果你真的想学习C++,你需要start with a good C++ book
  • 欢迎来到 Stack Overflow!听起来您可能需要学习如何使用debugger 来单步执行您的代码。使用好的调试器,您可以逐行执行您的程序,并查看它与您期望的偏差在哪里。如果您要进行任何编程,这是必不可少的工具。进一步阅读:How to debug small programs.
  • 不要在现代 C++ 中进行手动内存管理。 特别是如果您是新手。使用容器和智能指针。 不是 new/delete当然不是 malloc/calloc/realloc/free 在 C++ 中 - 从你的记忆中删除那些,忘记它们的存在 - C++ 不是 C.

标签: c matrix segmentation-fault memory-reallocation


【解决方案1】:

当您为p 重新分配内存时,您会向该数组添加一个新行(一个额外的指针)。但是你永远不会为那个新行分配内存,最终你会访问这个未初始化的指针。

但这不是真正的问题。在您想要将指针向上移动以为插入的行腾出空间的循环中,您的初始值和循环增量都是错误的。初始值为int i=r+1,对*(p+i) 的第一次写入将访问已分配空间(将是p[0]p[r])。循环增量应该是减量,--i。完成此循环后,您就可以为新行分配空间。

【讨论】:

  • 谢谢,我错过了那个微小的递减 :) 当我修复它时,我遇到了一个不同的问题,这是由于两个行指针在退出循环后指向同一个事情,然后我最终有两个相同的行(与插入的行相同)。我通过像这样更改那部分代码来修复它,并且我还为额外的行分配了内存,现在它可以工作了!
  • p=(int**)realloc(p,(r+1)*sizeof(int*)); if(p==NULL) printf("内存未分配。\n"); else{ (p+r)=(int)calloc(c-1,sizeof(int)); for(int i=r;i>row-1;i--){ for(int j=0;j
【解决方案2】:

正如这里的其他人所说,使用 std::vector 绝对更容易做到这一点。

但是,我假设您这样做是一种学习练习,所以我肯定会建议您完成此操作并了解您哪里出错了。你很接近,看起来你只是对你的索引感到困惑。尝试使用更具描述性的变量名称并将内容拆分为函数,以使其更难迷失在自己的代码中。

我修改了你的代码,让它做我认为你想做的事情。看看,让我知道这是否有帮助。

但是,是的,如果您将来从事任何 C++ 工作,请避免使用 C 风格的 malloc、alloc、free 等...并考虑使用 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;
}

【讨论】:

  • 如果您能指出您在哪里对代码进行了更改,那就太好了。对于它的价值,最后一个提示说“你想替换哪一行?”,但我猜代码应该插入一个新行,否则重新分配没有意义。但也许玛丽娜可以澄清一下。
猜你喜欢
  • 1970-01-01
  • 2015-02-13
  • 2014-08-04
  • 2012-11-19
  • 1970-01-01
  • 2013-04-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多