i';我使用realloc获得意外行为

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,

出于某种原因,每运行程序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, 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;colmat[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];
        }
    }