2012-01-21 4 views
0
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, но я не понимаю логически, как это происходит.

EDIT: Было указано, что в последнем раунде цикла 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

Тогда мой ответ ниже. –

+0

Вы здесь не делаете 'malloc' или' realloc'. Вы действительно думаете, что с этим кодом возникает проблема с утечкой памяти? Я думаю, что проблема может быть связана с другим фрагментом кода, в котором вы выделяете память. – c0da

+0

Я не вижу ничего явно неправильного. Можете ли вы опубликовать точные ошибки, которые вы получаете от valgrind? –

ответ

3

servers_ptr имеет размер MAXRECORDS. В этой последней итерации цикла for, k == MAX_RECORDS - 1. Вы получаете доступ к servers_ptr[k+1], который будет servers_ptr[MAX_RECORDS], который находится за концом массива. Это неопределенное поведение и флаги 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; 
      } 

Рассмотрите это предложение else. Его так же, как:

slist->servers_ptr[k] = slist->servers_ptr[k+1]; 

Потому что мы знаем, что slist->server_ptr[k+1] является NULL, потому что мы провалили, если условие. Но это означает, что обе ветви if одинаковы. Таким образом, код эквивалентен:

  for(k=i; k<MAXRECORDS; k++) { 
       slist->servers_ptr[k] = slist->servers_ptr[k+1]; 
      } 

Итак, что вы делаете, сдвигая все указатели влево, как это:

[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; 
+0

Отличное объяснение. Я попробую, спасибо! –

Смежные вопросы