i';我使用realloc获得意外行为
出于某种原因,每运行程序2-3次,我就会得到意外的值,例如-84215041-84215041,每隔一次我就会得到正确的结果:7 9 我是一名学生,如果代码有点学术性,我很抱歉 请参阅代码:i';我使用realloc获得意外行为,c,visual-studio-2019,realloc,C,Visual Studio 2019,Realloc,出于某种原因,每运行程序2-3次,我就会得到意外的值,例如-84215041-84215041,每隔一次我就会得到正确的结果:7 9 我是一名学生,如果代码有点学术性,我很抱歉 请参阅代码: int mat[ROW][COL] = { {2,-3,5,1,2}, {2,4,7,7,1}, {1,9,7,3,0} }; int row, col, tempRow = 0, tempCol = 0, indexCol, indexRow = 0, loopTempRow,
int mat[ROW][COL] = {
{2,-3,5,1,2},
{2,4,7,7,1},
{1,9,7,3,0}
};
int row, col, tempRow = 0, tempCol = 0, indexCol, indexRow = 0, loopTempRow, flag = 0, cnt = 1, loopTempCol = 0;
int* arr;
int* ptrArr;
arr = (int*)malloc(cnt * sizeof(int)); // mallocating an array with size 1 * int
ptrArr = arr;
if (arr == NULL) // checking allocation done succefully
{
printf("Error Allocating Memory\n");
exit(1);
}
for (row = 0; row < ROW; row++) // starting from row 0 we will wheck col 0,1,2,3,4 for the highest val.
{
flag = 1;
tempCol = 0;
for (col = 0; col < COL; col++)
{
if (mat[row][col] > tempCol)
{
tempCol = mat[row][col];
indexCol = col;
}
}
for (loopTempRow = 0; loopTempRow < ROW; loopTempRow++) // then we will check the row of the col index
{
if (mat[loopTempRow][indexCol] > tempCol)
{
flag = 0;
break;
}
}
if (flag == 1)
{
cnt++; // this is a counter for realloctaing.
arr = realloc(arr, (cnt - 1) * sizeof(int)); // every iteration the arr is increasing by 1
printf("mat[%d][%d] = %d\n", row, indexCol, mat[row][indexCol]);
*ptrArr = mat[row][indexCol]; // inserting the element into the arr
ptrArr++;
}
}
if (cnt == 1) // if the cnt = 1, it means that flag didn't became 1. which meant no value inserted to the arr
arr = NULL;
for (ptrArr = arr; ptrArr - arr < cnt - 1; ptrArr++) // print arr
printf("%d\t", *ptrArr);
free(arr);
最初为一个整数分配一个具有空间的数组,但从未设置该整数值。我猜这是因为分配一个0字节的块返回NULL,您认为这是一个错误
另一个令人困惑的代码片段是
cnt++;//这是一个realloctaing的计数器。
arr=realloc(arr,(cnt-1)*sizeof(int));//每次迭代,arr增加1
如果希望分配数组的大小是我们拥有标志==1的次数,为什么要将cnt
初始化为1
此外,您从未在该数组中写入任何值。给*ptrArr
赋值最多只能覆盖数组的第一个值
另一个问题是您最初将arr
复制到ptrArr
。稍后,如果flag==1
您将重新分配arr
。重新分配意味着可以取消分配(空闲)输入数组,并分配一个新的更大的块。在这种情况下,当您稍后为*ptrArr
赋值时,您将不会写入arr
。您将在不应写入的释放空间中写入。更糟糕的是,如果同时重新分配了空间,您可能会错误地覆盖有效数据,这是一个非常棘手的调试问题
我的印象是,你认为重新分配会在街区前面创造空间。这是不对的。拉洛克,延长封锁线。因此,当块的大小增加时,会在块的末尾添加空间
这意味着当flag==1时,必须将mat[row][indexCol]
附加到数组arr
下面是您应该如何处理阵列
//将数组初始化为空
int-cnt=0;
int*arr=NULL;
请注意,分配一个0字节的块取决于实现。它可能返回NULL,也可能不返回NULL。在这里,我们确定空数组为NULL,并且具有cnt==0
以下代码将值mat[row][indexCol]
附加到数组中:
//将mat[row][indexCol]追加到数组arr
arr=realloc(arr,(cnt+1)*sizeof(int));
arr[cnt++]=mat[row][indexCol];
这在arr
为空时起作用,因为realloc将分配一个新块
要打印数组中的所有值,请执行以下操作:
for(int i=0;i
当cnt==0
时,如果arr==NULL
没有关系,因为当cnt==0
时,永远不会访问arr
代码中还有一个错误,它定位了一行中的最大值
使用0初始化tempCol
,并将值与之进行比较。如果该行仅包含全部小于0的负值,则算法将无法找到该行中的最大值
为了找到一行中的最大值,您有两个选项
使用尽可能小的值初始化tempCol:INT#u MIN(#include)
使用以下代码可以消除对tempCol
的需要
indexCol=0;
for(col=1;col mat[row][indexCol])
indexCol=col;
//这里,indexCol是行中最大值的索引
您的问题很可能是由于使用了ptrAtr
。您将其初始化为arr
的开头,但随后您将realloc
arr
并且不能保证arr
将保留在相同的内存位置,这意味着ptrArr
将不再指向它
您最好像这样使用arr
索引
int cnt = 0;
arr = (int*)malloc(cnt * sizeof(int));
// stuff happens
if (flag == 1)
{
arr = realloc(arr, (cnt + 1) * sizeof(int));
printf("mat[%d][%d] = %d\n", row, indexCol, mat[row][indexCol]);
arr[cnt++] = mat[row][indexCol];
}
}
因此,删除-1
cnt++
和cnt-1
?将cnt
的值增加1,但随后使用cnt
的旧值进行重新分配。值-84215051表示正在读取未初始化的已分配堆内存。如果(cnt==1)arr=NULL,则代码>表示您将发生内存泄漏。我认为你需要在睡了一个好觉后坐下来,重新思考一下arr
的逻辑,以及你如何处理它和它的重新分配。@Someprogrammerdude,谢谢你的建议。我需要做的任务之一是,如果没有值,那么我需要将NULL返回给arr。这就是任务。cnt只有在满足条件时才会增加。我用1开始cnt,因为我用的是malloc。亲爱的chmike,非常感谢您详细和专业的帮助。事实上,问题似乎在于ptrArr。我当然从你的评论中学到了很多。
int cnt = 0;
arr = (int*)malloc(cnt * sizeof(int));
// stuff happens
if (flag == 1)
{
arr = realloc(arr, (cnt + 1) * sizeof(int));
printf("mat[%d][%d] = %d\n", row, indexCol, mat[row][indexCol]);
arr[cnt++] = mat[row][indexCol];
}
}