C ++ смешивает мои строки? - PullRequest
       19

C ++ смешивает мои строки?

1 голос
/ 13 февраля 2012

У меня есть эта действительно простая функция на С ++, которую я написал сам.
Он должен просто удалить символы «-» из моей строки.
Вот код

char* FastaManager::stripAlignment(char *seq, int seqLength){
    char newSeq[seqLength];
    int j=0;
    for (int i=0; i<seqLength; i++) {
        if (seq[i] != '-') {
            newSeq[j++]=seq[i];
        }
    }

    char *retSeq = (char*)malloc((--j)*sizeof(char));
    for (int i=0; i<j; i++) {
        retSeq[i]=newSeq[i];
    }
    retSeq[j+1]='\0'; //WTF it keeps reading from memory without this
    return retSeq;
}

Я думаю, этот комментарий говорит сам за себя.
Я не знаю почему, но когда я запускаю программу и распечатываю результат, я получаю что-то вроде

'stripped_sequence''original_sequence'

Однако, если я попытаюсь отладить код, чтобы увидеть, есть ли что-то не так, потоки идут правильно и заканчивают тем, что возвращают правильную очищенную последовательность.

Я попытался распечатать память двух переменных, и вот показания памяти

память для seq: http://i.stack.imgur.com/dHI8k.png

память для * seq: http://i.stack.imgur.com/UqVkX.png

память для retSeq: http://i.stack.imgur.com/o9uvI.png

память для * retSeq: http://i.stack.imgur.com/ioFsu.png

(не удалось включить ссылки / картинки из-за спам-фильтра, извините)

Это код, который я использую для распечатки строк

for (int i=0; i<atoi(argv[2]); i++) {
    char *seq;
    if (usingStructure) {
        seq = fm.generateSequenceWithStructure(structure);            
    }else{
        seq = fm.generateSequenceFromProfile();
    }
    cout<<">Sequence "<<i+1<<": "<<seq<<endl;
}

Теперь я действительно не знаю, что происходит.

Ответы [ 3 ]

2 голосов
/ 13 февраля 2012

Если вы можете использовать std :: string, просто сделайте это:

std::string FastaManager::stripAlignment(const std::string& str)
{
   std::string result(str);
   result.erase(std::remove(result.begin(), result.end(), '-'), result.end());
   return result;
}

Это называется " стирание-удаление идиома ".

1 голос
/ 13 февраля 2012

Лично я думаю, что вам лучше использовать std::string, если у вас нет действительно очень веской причины, иначе:

std::string FastaManager::stripAlignment(std::string value)
{
    value.erase(std::remove(value.begin(), value.end(), value.begin(), '-'), value.end());
    return value;
}

Когда вы используете строки C, вы должны понимать, что они заканчиваются нулем.: Строки C доходят до первого найденного нулевого символа.В коде, который вы разместили, вы ввели присвоение вне диапазона, когда вы присвоили элементы 'j' и присваиваете retSeq[j + 1], что на два символа после конца строки (в любом случае вы наверняка имеете в виду retSeq[j] = 0;).

1 голос
/ 13 февраля 2012

Это происходит потому, что вы помещаете завершающий ноль строки C за пределы выделенного пространства.Вам следует выделить один дополнительный символ в конце вашей строковой копии и добавить туда '\0'.Или, что еще лучше, вы должны использовать std::string.

char *retSeq = (char*)malloc((j+1)*sizeof(char));
for (int i=0; i<j; i++) {
    retSeq[i]=newSeq[i];
}
retSeq[j]='\0';

, который продолжает чтение из памяти без этого

Это по замыслу: строки C заканчиваются нулем,'\0' сигнализирует строковым подпрограммам в C, что конец строки достигнут.То же соглашение действует в C ++ при работе со строками C.

...