关于realloc再循环体内,第一次开辟成功,第二次失败的问题
void BSTreeDATAPush(BSTree* T){
int chose;//用来限制循环体
do
{
if(DATAsub == num)
{
num = num+4;
BSTData* tmp = (BSTData*)realloc(T->DATA,sizeof(BSTData)*num);
if(!tmp)
{
printf("%s\n",strerror(errno));
exit(-1);
}
T->DATA = tmp;
free(tmp);
tmp = NULL;
}
printf("请插入数据:>");
scanf("%d",&(T->DATA));
rewind(stdin);
DATAsub++;
printf("是否继续插入结点数据? 1.继续 0.退出 :>");
scanf("%d",&chose);
rewind(stdin);
//以上是仅存放需排序的无序数组信息。
} while (chose);
printf("结点数据录入结束。\n");
return ;
}
两个全局变量,num是专门用来开辟数组空间的变量;Datasub是数组的下标.
函数是我输入需要排序的数组用的,输入完数据它的值应该是和数组内存放的数据量是相同的。初始化接口里,已经开辟了4个int大小,在我输入第五个数据的时候,realloc没有提示出错。当第二次,也就是下标为8的时候,vscode提示分段错误。
也就是sub = 8; num = 12时,提示分段错误,还不是error报的……
我瞅了半天,也没见哪里有非法访问。 有没大佬解读一下? 根据给出的代码,问题可能在realloc和free的使用上。重点如下:
- realloc函数返回的是一个指针,该指针指向重新分配大小后的空间。所以这里需要将 realloc 的返回值赋值给 tmp,而不是 BSTData* 类型的 T->DATA。
- 在进行 realloc 调用之后,我们无需再次释放旧内存块,因为 realloc 函数已经执行了此操作。
- 需要仔细检查调用realloc之前数据数组 DATA 中的所有访问是否都在有效范围内。这也是引起段错误的一种常见原因。
请看修改后的代码:
void BSTreeDATAPush(BSTree* T)
{
int chose;//用来限制循环体
do
{
if(DATAsub == num) {
num = num+4;
BSTData* tmp = (BSTData*)realloc(T->DATA,sizeof(BSTData)*num);
if(!tmp) {
printf("%s\n",strerror(errno));
exit(-1);
}
T->DATA = tmp; // 此处将 realloc 函数返回值赋值给 T->DATA
}
printf("请插入数据:>");
scanf("%d",&(T->DATA));
rewind(stdin);
DATAsub++;
printf("是否继续插入结点数据? 1.继续 0.退出 :>");
scanf("%d",&chose);
rewind(stdin);
//以上是仅存放需排序的无序数组信息。
} while (chose);
printf("结点数据录入结束。\n");
return ;
}
您的代码存在一个错误,这可能是导致问题的原因。在执行 `realloc` 后,您立即调用了 `free(tmp);`。这样做会释放刚刚重新分配的内存,而您实际上还需要使用它。将 `free(tmp);` 这一行删除,问题应该会得到解决。此外,由于不再需要释放 `tmp`,您也可以将 `tmp = NULL;` 这一行删除。
修改后的代码如下:
void BSTreeDATAPush(BSTree* T)
{
int chose;//用来限制循环体
do
{
if(DATAsub == num)
{
num = num+4;
BSTData* tmp = (BSTData*)realloc(T->DATA,sizeof(BSTData)*num);
if(!tmp)
{
printf("%s\n",strerror(errno));
exit(-1);
}
T->DATA = tmp;
// 删除以下两行
// free(tmp);
// tmp = NULL;
}
printf("请插入数据:>");
scanf("%d",&(T->DATA));
rewind(stdin);
DATAsub++;
printf("是否继续插入结点数据? 1.继续 0.退出 :>");
scanf("%d",&chose);
rewind(stdin);
//以上是仅存放需排序的无序数组信息。
} while (chose);
printf("结点数据录入结束。\n");
return ;
}
这样修改后,您的代码应该可以正常工作。 isdkz 发表于 2023-4-25 21:14
您的代码存在一个错误,这可能是导致问题的原因。在执行 `realloc` 后,您立即调用了 `free(tmp);`。这样做 ...
谢谢,代码可以跑了,但是不释放会造成内存泄漏吧? Filthy-ice 发表于 2023-4-25 21:19
谢谢,代码可以跑了,但是不释放会造成内存泄漏吧?
不需要担心内存泄漏。在您的示例代码中,realloc用于重新分配内存。当realloc成功时,它会自动处理原始内存块的释放。所以,在这种情况下,您不需要手动释放原始内存块。
当realloc返回新的内存地址时,它已经在内部处理了原始内存块的释放,所以您只需关心新返回的内存地址。在这种情况下,手动释放tmp实际上是错误的,因为它会释放已经重新分配给T->DATA的内存。
一般来说,您需要在程序结束时或不再需要这些内存时手动释放内存。在这个例子中,当您不再需要T->DATA时,您应该调用`free(T->DATA);`来释放内存。这通常发生在程序结束前的某个地方,或者在您不再需要BSTree结构时。 sfqxx 发表于 2023-4-25 21:13
根据给出的代码,问题可能在realloc和free的使用上。重点如下:
- realloc函数返回的是一个指针,该指针 ...
明白了,学蒙了,是开辟的数组不再使用时需要释放。谢谢答疑。 Filthy-ice 发表于 2023-4-25 21:23
明白了,学蒙了,是开辟的数组不再使用时需要释放。谢谢答疑。
最佳绝缘体{:10_266:}
页:
[1]