C for循环中的内存泄漏 for(k=i;kserver_ptr[k+1]!=NULL){ slist->servers_ptr[k]=slist->servers_ptr[k+1]; }else slist->servers\u ptr[k]=NULL; }

C for循环中的内存泄漏 for(k=i;kserver_ptr[k+1]!=NULL){ slist->servers_ptr[k]=slist->servers_ptr[k+1]; }else slist->servers\u ptr[k]=NULL; },c,memory-leaks,for-loop,valgrind,C,Memory Leaks,For Loop,Valgrind,当我运行valgrind时,我得到一个无效大小为8的错误 我假设这与for循环中的边界情况有关,但我不明白它是如何发生的 编辑:有人指出,在for循环的最后一轮中,访问服务器\u ptr[k+1]在阵列之外,导致valgrind错误。此后,我将代码更新为: for(k=i; k<MAXRECORDS; k++) { if(slist->servers_ptr[k+1] != NULL) { slist->servers_ptr[k] = slist-&g

当我运行valgrind时,我得到一个无效大小为8的错误

我假设这与for循环中的边界情况有关,但我不明白它是如何发生的

编辑:有人指出,在for循环的最后一轮中,访问服务器\u ptr[k+1]在阵列之外,导致valgrind错误。此后,我将代码更新为:

for(k=i; k<MAXRECORDS; k++) {
    if(slist->servers_ptr[k+1] != NULL) {
        slist->servers_ptr[k] = slist->servers_ptr[k+1];
    } else slist->servers_ptr[k] = NULL;
}
for(k=i;kserver_ptr[k+1]!=NULL){
slist->servers_ptr[k]=slist->servers_ptr[k+1];
如果(k==MAXRECORDS-2)slist->servers\u ptr[k+1]=NULL;
}else slist->servers\u ptr[k]=NULL;
}

我仍然会在valgrind中发现错误。我更新不正确吗?

根据的
条件,这看起来像是一个bug:

for(k=i; k<MAXRECORDS-1; k++) {
        if(slist->servers_ptr[k+1] != NULL) {
                slist->servers_ptr[k] = slist->servers_ptr[k+1];
                if(k==MAXRECORDS-2)slist->servers_ptr[k+1] = NULL;
        } else slist->servers_ptr[k] = NULL;
}
因为它将读取超过
服务器\u ptr
数组的末尾


将条件更改为
k
如果
slist->servers\u ptr
是一个大小为
MAXRECORDS
的数组,那么当
k=MAXRECORDS-1
时,访问元素
k+1
将超出数组的边界


因为0是数组的第一个元素,所以10是数组的第十一个元素。大小为10的数组没有第十一个元素。

这几乎可以肯定,因为您要超出数组的末尾。
k
的最大值是
MAXRECORDS-1
,您在表达式中使用了
k+1

这意味着您将访问
array[MAXRECORDS]
,其中索引应限制在
0
MAXRECORDS-1(含)之间

在没有更多上下文的情况下,很难看到您正在尝试做什么,但是修复可能很简单,就像使用
k
作为
循环继续条件(中间的位):

只有最后一次分配才可访问


顺便说一句,如果你想要的是随机删除,那么(在我看来)最好是这样做:

//对于存在非空下一个元素的每个元素,
//将该元素向下移动。然后强制最后一个元素
//为空(它将已经下移)。
对于(k=i;(kservers_ptr[k+1]!=NULL);k++)
slist->servers_ptr[k]=slist->servers_ptr[k+1];
slist->servers\u ptr[k]=NULL;

额外条件在下一个元素为NULL时停止,并将NULL放置到该位置。这应该可以很好地工作,并且具有不太复杂的优点。

MAXRECORDS=10,并且slist->servers\u ptr[]是大小MAXRECORDS。这不是内存泄漏,Valgrind消息告诉您正在覆盖或过度读取分配内存的边界(在您的案例数组中)。您是否将
servers\u ptr
声明为
servers\u ptr[MAXRECORDS+1]
?否则,当
k=MAXRECORDS-1
时,您的阅读就到此为止了。将额外信息添加到问题中,而不是作为注释。我这次为您做了这件事,但为了将来。(您可以删除我为您传输的注释;但我不能这样做。)谢谢你们的回复,伙计们。它声明为servers_ptr[MAXRECORDS]。我更新了我的问题,我的解决方案在逻辑上解决了吗?这很有意义。谢谢!我更新了for循环中的边界,但仍然在valgrind中遇到同样的问题。谢谢:)我更改了for循环中的条件,但仍然出现错误:(那更干净了,你说得对。解释得也很好,我来试试看。
if((slist->servers_ptr[k+1] != NULL)
for (k = i; k < MAXRECORDS - 1; k++) {
char *x;
for (i = 0; i < 10; i++)
    x = malloc (64);
// For every element where there's a non-NULL next element,
// shift that element down. Then force the last element to
// be NULL (it will have been shifted down already).  

for (k = i; (k < MAXRECORDS - 1) && (slist->servers_ptr[k+1] != NULL); k++)
    slist->servers_ptr[k] = slist->servers_ptr[k+1];
slist->servers_ptr[k] = NULL;