C ошибка управления памятью?

Вот измененная версия функции StrToNumber. Как прежде,

  1. Это позволяет дополнительному знаку появиться впереди или позади числового значения.
  2. Это выполняет проверку, чтобы проверить, что существует только один знак в голове или хвосте строки.
  3. , Если ошибка происходит, "переданное" значение по умолчанию возвращается.

Этот ответ является возможным решением, которое лучше подходит для начального вопроса, чем мое предыдущее сообщение.

   static StrToNumber(val: string, defaultVal:number = 0): number
   {        
      let result:number = defaultVal;      
      if(val == null) 
         return result;            
      if(val.length == 0) 
         return result;      
      val = val.trim();
      if(val.length == 0) 
         return(result);
      let sign:number = 1;     
      //
      // . obtain sign from string, and place result in "sign" local variable. The Sign naturally defaults to positive
      //     1 for positive, -1 for negative.
      // . remove sign character from val. 
      //      Note, before the function returns, the result is multiplied by the sign local variable to reflect the sign.
      // . error check for multiple sign characters
      // . error check to make sure sign character is at the head or tail of the string
      //              
      {  
         let positiveSignIndex = val.indexOf('+');
         let negativeSignIndex = val.indexOf('-');
         let nTailIndex = val.length-1;
         //
         // make sure both negative and positive signs are not in the string
         //
         if( (positiveSignIndex != -1) && (negativeSignIndex != -1) ) 
             return result;
         //
         // handle postive sign
         //
         if (positiveSignIndex != -1)
         {
            //
            // make sure there is only one sign character
            //
            if( (positiveSignIndex != val.lastIndexOf('+')) )
             return result;     
             //
             // make sure the sign is at the head or tail
             //
             if( (positiveSignIndex > 0) && (positiveSignIndex < nTailIndex )  )
                 return result;
             //
             // remove sign from string
             //
             val = val.replace("+","").trim();                 
         }    
         //
         // handle negative sign
         //
         if (negativeSignIndex != -1)
         {
            //
            // make sure there is only one sign character
            //
            if( (negativeSignIndex != val.lastIndexOf('-')) )
             return result;     
             //
             // make sure the sign is at the head or tail
             //
             if( (negativeSignIndex > 0) && (negativeSignIndex < nTailIndex )  )
                 return result;
             //
             // remove sign from string
             //
             val = val.replace("-","").trim();  
             sign = -1;                 
         }               
         //
         // make sure text length is greater than 0
         //       
         if(val.length == 0) 
            return result;                             
      }   
      //
      // convert string to a number
      //
      var r = +(<any>val);
      if( (r != null) && (!isNaN(r)) )
      {          
         result = r*sign;         
      }
      return(result);    
   }
6
задан Charlie Epps 3 September 2009 в 07:34
поделиться

6 ответов

У вас несколько проблем.

Здесь вы выделяете пространство для 5 символов, но скопируйте 6 в (символ конца строки в конце строки также требует пробела):

  frag->seq = malloc (5 * sizeof (char));
  strcpy (frag->seq, "55555");

В то же время вы никогда не устанавливаете frag-> next во втором frag вы выделяете. Вам нужно установить его на NULL , чтобы цикл while в подпрограмме free_frag не ускользнул от сорняков.

Третья проблема здесь:

  /* to do : free fragment */
  free (fragment);

Вы освобождаете фрагмент , но это не целый блок, полученный от malloc - это всего лишь один из отдельных блоков из 10 фрагментов, выделенных за один раз. Более поздний free (frags) правильно освобождает этот блок, поэтому вам просто нужно удалить эту ошибочную строку.

9
ответ дан 8 December 2019 в 03:40
поделиться

Вы пытаетесь освободить середину вашего массива.

Fragment *fragment = &frags[i];
...
...
/* to do : free fragment */
free (fragment);
fragment = NULL;
7
ответ дан 8 December 2019 в 03:40
поделиться

Вы обрабатываете frag_list как связанный список Frag указателей, но вы не добавляете терминатор при создании списка.

Попробуйте следующее:

int
main ()
{
  Fragment *frags = (Fragment *) malloc (10 * sizeof (Fragment));
  int i, j;
  for (i = 0; i < 10; i++)
    {
      Fragment *fragment = &frags[i];
      fragment->frag_list = (Frag *) malloc (1 * sizeof (Frag));
      Frag *frag = fragment->frag_list;
      frag->seq = malloc (5 * sizeof (char));
      strcpy (frag->seq, "55555");
      frag->next = (Frag *) malloc (1 * sizeof (Frag));
      frag = frag->next;
      frag->seq = malloc (5 * sizeof (char));
      strcpy (frag->seq, "55555");
      frag->next = NULL; // <--------------------- This is what you need to do
    }
  free_frags (frags, 10);
  return 0;
}

Проблема в том, что когда вы malloc () новый блока памяти, компилятор и / или ОС могут обнулить его для вас, но, скорее всего, это просто выдаст вам мусор. При попытке free () этого мусора происходит сбой.

3
ответ дан 8 December 2019 в 03:40
поделиться

Похоже, что эти строки имеют Bufferoverflow

  frag->seq = malloc (5 * sizeof (char));
  strcpy (frag->seq, "55555");

, потому что строка 55555 также будет включать завершающий нулевой символ, который также записывается в память за пределами выделенных 5 байтов.

Вместо этого вы можете использовать strdup () , который выделяет и копирует строку

  frag->seq = strdup("55555");
7
ответ дан 8 December 2019 в 03:40
поделиться

Если вы собираетесь использовать указатель Frag.next в качестве дозорного (в free_frags ()), вам нужно установить его в NULL где-нибудь в вашем коде.

Кроме того, будьте осторожно - вы используете malloc () для выделения 5 символов для Frag.seq и копируете в это пространство строку, не оканчивающуюся NULL.

2
ответ дан 8 December 2019 в 03:40
поделиться

Вы ссылаетесь на адрес памяти, который вам не принадлежит. Это происходит в функции free_frags (), а именно в строке 41, free (фрагмент); .

0
ответ дан 8 December 2019 в 03:40
поделиться
Другие вопросы по тегам:

Похожие вопросы: