for循环中的内存泄漏

时间:2012-01-21 04:28:59

标签: c memory-leaks for-loop 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;
}

当我运行valgrind时,出现无效大小8的错误。

我认为这与我的for循环中的边框情况有关,但我不明白它是如何发生的。

编辑:有人指出,在for循环的最后一轮,访问servers_ptr [k + 1]是在数组之外,导致valgrind错误。我已经将我的代码更新为:

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;
}

我仍然在valgrind中得到错误。我错误地更新了吗?

3 个答案:

答案 0 :(得分:3)

如果slist->servers_ptr是一个大小为MAXRECORDS的数组,则k+1时访问元素k = MAXRECORDS - 1将超出数组的范围。

由于0是数组的第一个元素,因此10是数组的第11个元素。大小为10的数组没有第11个元素。

答案 1 :(得分:3)

几乎可以肯定,因为你超越了阵列的末尾。 k的最大值为MAXRECORDS-1,您在表达式中使用k+1

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

如果没有更多上下文,很难看到你要做的事情,但修复可能就像使用k < MAXRECORDS - 1作为for循环继续条件一样简单(位于中间位置):

for (k = i; k < MAXRECORDS - 1; k++) {

其他可能性是i的无效值,例如-1,这会导致数组另一端出现问题。这可能不太可能,因为我假设您通过将所有其他元素向下移动来删除元素i(如:i将被设置为有效索引)。


顺便说一下,这不是内存泄漏,只是内存损坏。内存泄漏是指您分配内存然后丢失指向它们的指针,以便它们永远不会被释放,例如:

char *x;
for (i = 0; i < 10; i++)
    x = malloc (64);

只能访问 last 分配。


顺便说一句,如果你正在追求一个改组删除,那么(在我看来)做得更好:

// 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;

额外条件在下一个元素为NULL的位置停止,并将NULL置于该位置。这应该很好,并且具有不太复杂的优点。

答案 2 :(得分:2)

基于for条件,这看起来像一个错误:

if((slist->servers_ptr[k+1] != NULL)

因为它会读取servers_ptr数组的结尾。

将条件更改为k < MAXRECORDS - 1