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的错误。
请注意MAXRECORDS = 10
,数组大小为MAXRECORDS
。
我认为这与我的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)
servers_ptr
的大小为MAXRECORDS
。在for循环的最后一次迭代中,k == MAX_RECORDS - 1
。您可以访问servers_ptr[k+1]
servers_ptr[MAX_RECORDS]
,它是一个超出数组末尾的 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标记它。
slist->servers_ptr[k] = slist->servers_ptr[k+1];
考虑那个else子句。它与以下相同:
slist->server_ptr[k+1]
因为我们知道 for(k=i; k<MAXRECORDS; k++) {
slist->servers_ptr[k] = slist->servers_ptr[k+1];
}
为NULL,因为我们失败了if条件。但这意味着if的两个分支都是相同的。所以代码相当于:
[1][2][3][4][5]
[2][3][4][5][?]
所以你正在做的是将所有指针移动到左边:
for(k=i; k<MAXRECORDS-1; k++) {
slist->servers_ptr[k] = slist->servers_ptr[k+1];
}
slist->servers_ptr[MAXRECORDS-1] = NULL;
您的代码尝试将一个值转换为多个并最终从某个地方提取垃圾。
解决方案是复制少一个项目并将最后一个单元格作为特例处理。
{{1}}