Вот измененная версия функции StrToNumber. Как прежде,
Этот ответ является возможным решением, которое лучше подходит для начального вопроса, чем мое предыдущее сообщение.
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);
}
У вас несколько проблем.
Здесь вы выделяете пространство для 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)
правильно освобождает этот блок, поэтому вам просто нужно удалить эту ошибочную строку.
Вы пытаетесь освободить середину вашего массива.
Fragment *fragment = &frags[i];
...
...
/* to do : free fragment */
free (fragment);
fragment = NULL;
Вы обрабатываете 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 ()
этого мусора происходит сбой.
Похоже, что эти строки имеют Bufferoverflow
frag->seq = malloc (5 * sizeof (char));
strcpy (frag->seq, "55555");
, потому что строка 55555
также будет включать завершающий нулевой символ, который также записывается в память за пределами выделенных 5 байтов.
Вместо этого вы можете использовать strdup ()
, который выделяет и копирует строку
frag->seq = strdup("55555");
Если вы собираетесь использовать указатель Frag.next в качестве дозорного (в free_frags ()), вам нужно установить его в NULL где-нибудь в вашем коде.
Кроме того, будьте осторожно - вы используете malloc () для выделения 5 символов для Frag.seq и копируете в это пространство строку, не оканчивающуюся NULL.
Вы ссылаетесь на адрес памяти, который вам не принадлежит. Это происходит в функции free_frags (), а именно в строке 41, free (фрагмент); .