Невозможно освободить переменную на основе stati c - PullRequest
1 голос
/ 07 мая 2020

Я получаю странные результаты при попытке освободить переменную на основе stati c. Ниже представлена ​​небольшая тестовая программа, которую я создал для демонстрации проблемы, с которой я столкнулся. Переменная на основе stati c находится в подпроцедуре proc1 этой тестовой программы. Его имя - myIx, с указателем на основе myIx_p. Я помещаю комментарии в основной текст программы, чтобы указать на возникающие у меня проблемы. Что здесь не так?

 D ix              s              5i 0                                                       

  /free                                                                                      
   ix = proc1(*off);     // ix is 1 after this statement => Expected                          
   ix = proc1(*off);     // ix is 2 after this statement => Expected.                         
   ix = proc1(*on);      // ix is 0, which is expected.  But myIx_p is not being set to null => NOT Expected
   ix = proc1(*off);     // ix is 3 after this statement => NOT Expected.  Expecting 1.       
   ix = proc1(*on);      // try to shutdown again and get CEE0810 error => NOT Expected                          

   *inlr = *on;                                                                              

  *------------------------------------------------------------------------------------------
  * proc1 to test based static variable                                                      
  *------------------------------------------------------------------------------------------
 P proc1           B                                                                         
 D                 pi             5i 0                                                       
 D  piShutDown                     n   const                                                 
 D myIx            s              5i 0 based(myIx_p)                                         
 D myIx_p          s               *   static                                                

    // caller only wants to shutdown the proc        
    if (piShutDown and myIx_p <> *null);             
      dealloc myIx_p;                                
      return 0;                                      
    endif;                                           

    // allocate myIx if not yet allocated            
    if (myIx_p = *null);                             
      myIx_p = %alloc(%size(myIx));                  
    endif;                                           

    // increase the value by 1 as a test             
    myIx += 1;                                       

    return myIx;                                     

 P                 E                                 
  /end-free                                                                                          

1 Ответ

2 голосов
/ 07 мая 2020

Ответ прямо в ваших комментариях. Вы не ставите myIx_p = *null после dealloc. Невозможность установить для него значение *null означает, что он по-прежнему указывает на то же место в памяти, которое было только операционной системой, которое больше не видит его как выделенное. Наблюдаемое вами поведение вполне ожидаемо. Исправление очень просто:

// caller only wants to shutdown the proc        
if (piShutDown and myIx_p <> *null);             
  dealloc myIx_p;
  myIx_p = *null;                                
  return 0;                                      
endif;                                           

Вы также можете разрешить его, как указано в документации IBMi:

// caller only wants to shutdown the proc        
if (piShutDown and myIx_p <> *null);             
  dealloc(n) myIx_p;
  return 0;                                      
endif; 

Если вы не используете (n), вы должны установите для него значение * null, как в первом примере. См. Документацию по dealloc здесь: https://www.ibm.com/support/knowledgecenter/en/ssw_ibm_i_74/rzasd/zzdeall.htm

...