утечка памяти в цикле for - PullRequest
0 голосов
/ 21 января 2012
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, но я логически не понимаю, как это происходит.

РЕДАКТИРОВАТЬ: было указано, что в последнем цикле цикла доступ к 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 ]

3 голосов
/ 21 января 2012

Если slist->servers_ptr является массивом размером MAXRECORDS, то доступ к элементу k+1 будет выходить за границы массива, когда k = MAXRECORDS - 1.

Поскольку 0 является первым элементом массива, 10является одиннадцатым элементом массива.Массив размера 10 не имеет одиннадцатого элемента.

3 голосов
/ 21 января 2012

Это почти наверняка, потому что вы выходите за пределы массива. Максимальное значение k равно MAXRECORDS-1, и вы используете k+1 в выражениях.

Это означает, что вы получите доступ к array[MAXRECORDS], где индекс должен быть ограничен от 0 до MAXRECORDS - 1 включительно.

Сложно увидеть, что вы пытаетесь сделать без дополнительного контекста, но исправление может быть таким же простым, как использование k < MAXRECORDS - 1 в качестве условия продолжения цикла for (бит в середине) :

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

Возможность other является недопустимым значением i, например, -1, что может вызвать проблему на другом конце массива. Это, вероятно, менее вероятно, так как я предполагаю, что вы удаляете элемент i, сдвигая все остальные элементы вниз (как в: i будет установлен в допустимый индекс).


Кстати, это не память утечка , просто повреждение памяти. Утечки памяти - это когда вы выделяете память, а затем теряете указатели на них, чтобы их никогда не освободить, что-то вроде:

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;

Дополнительное условие останавливается, когда следующий элемент равен NULL, и помещает NULL в эту позицию. Это должно работать нормально и иметь преимущество в том, что оно менее сложное.

2 голосов
/ 21 января 2012

Исходя из условия for, это выглядит как ошибка:

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

, поскольку она будет считываться после конца массива servers_ptr.

Измените условие наk < MAXRECORDS - 1.

...