动态内存分配中的 Segmentation fault (core dumped) 错误
Segmentation fault (core dumped) error in dynamic memory allocation
我是编码新手,也是 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::vector 绝对更容易做到这一点。
但是,我假设您是将此作为学习练习进行的,因此我绝对建议您完成此操作并了解哪里出了问题。你很接近,看起来你只是对你的指数感到困惑。尝试使用更具描述性的变量名称并将内容拆分为函数,以使其更难迷失在您自己的代码中。
我修改了您的代码以使其执行我认为您正在尝试执行的操作。看一看,让我知道这是否有帮助。
但是,是的,如果您将来要进行任何 C++ 工作,请避免使用 C 风格的 malloc、alloc、free 等...并考虑使用标准库。
#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;
}
当您为 p
重新分配内存时,您会向该数组添加一个新行(一个额外的指针)。但是您从未为该新行分配内存,最终您访问了这个未初始化的指针。
但这不是真正的问题。在您想要将指针向上移动以使插入的行 space 的循环中,您的初始值和循环增量都是错误的。初始值为 int i=r+1
,第一次写入 *(p+i)
将访问分配的 space 之后的一个(即 p[0]
到 p[r]
)。循环增量应该是减量,--i
。完成此循环后,您可以为新行分配 space。
我是编码新手,也是 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::vector 绝对更容易做到这一点。
但是,我假设您是将此作为学习练习进行的,因此我绝对建议您完成此操作并了解哪里出了问题。你很接近,看起来你只是对你的指数感到困惑。尝试使用更具描述性的变量名称并将内容拆分为函数,以使其更难迷失在您自己的代码中。
我修改了您的代码以使其执行我认为您正在尝试执行的操作。看一看,让我知道这是否有帮助。
但是,是的,如果您将来要进行任何 C++ 工作,请避免使用 C 风格的 malloc、alloc、free 等...并考虑使用标准库。
#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;
}
当您为 p
重新分配内存时,您会向该数组添加一个新行(一个额外的指针)。但是您从未为该新行分配内存,最终您访问了这个未初始化的指针。
但这不是真正的问题。在您想要将指针向上移动以使插入的行 space 的循环中,您的初始值和循环增量都是错误的。初始值为 int i=r+1
,第一次写入 *(p+i)
将访问分配的 space 之后的一个(即 p[0]
到 p[r]
)。循环增量应该是减量,--i
。完成此循环后,您可以为新行分配 space。