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中得到错误。我错误地更新了吗?
答案 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]
,其中索引应限制在0
和MAXRECORDS - 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
。