ОШИБКА: AddressSanitizer: отрицательный размер-параметр: (размер = -1) - PullRequest
0 голосов
/ 09 апреля 2020

Извините за этот грязный код, но у меня есть вопрос.

Я пытался решить задачу LeetCode 844. Принимая во внимание, что

Учитывая две строки S и T, возвращаются, если они равны, когда обе они введены в пустые текстовые редакторы. # означает символ возврата на одну позицию.


1-й пример

Ввод: S = "ab # c", T = " ad # c "
Вывод: true
Объяснение: S и T становятся" c ".

2-й пример

Ввод: S = "ab ##", T = "c # d #"
Вывод: true
Объяснение: И S, и T становятся "".

Мое решение здесь:

class Solution {
public:
    bool backspaceCompare(string S, string T) {
        vector<char> a;
        vector<char> b;
        int id = 0; 
        for(int i = 0; i < S.length(); i++){
            a.push_back(S[i]);
            id++;
            if(S[i]=='#'){
                a.erase(a.begin()+id-2);
                id--;
                a.erase(a.begin()+id-1);
                id--;
            }
            if(S[i+1]=='#'){
                a.erase(a.begin()+id-1);  
                id--;
                i+=2;
            } 
        }id = 0;
        for(int i = 0; i < T.length(); i++){  
            b.push_back(T[i]);
            id++;
            if(T[i]=='#'){
                b.erase(b.begin()+id-2);
                id--;
                b.erase(b.begin()+id-1);
                id--;
            }
            if(T[i+1]=='#'){
                b.erase(b.begin()+id-1);
                i+=2;
            }
        }
        bool x;
        if(a.size()==0) x = true;
        else{
            for(int i = 0; i < a.size(); i++){
                if(a[i]==b[i]) x = true;
                else x = false;
            }
        }return x;
    }
};
//Input: S = "ab##", T = "c#d#"

Сообщение об ошибке во время выполнения

================== ====================================================
= = 32 == ОШИБКА: AddressSanitizer: параметр отрицательного размера: (размер = -1)
# 8 0x7f585c70d82f (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
0x602000000151 находится в 0 байтах справа от 1-байтовой области [0x602000000150,0x602000000151)
, выделенной потоком T0 здесь:
# 5 0x7f585c70d82f (/ lib / x86_64- linux -gnu / lib c .so.6 + 0x2082f)
== 32 == ABORTING

Но это дает мне такую ​​ошибку. Я думаю, что все хорошо здесь с размером. Где моя ошибка?

1 Ответ

0 голосов
/ 09 апреля 2020

У вас есть несколько ошибок в вашем коде

int id = 0; 

for (int i = 0; i < S.length(); i++){
    a.push_back(S[i]);
    id++;
    if (S[i]=='#'){
        a.erase(a.begin()+id-2);
        id--;
        a.erase(a.begin()+id-1);
        id--;
    }
    if(S[i+1]=='#'){
        a.erase(a.begin()+id-1);  
        id--;
        i+=2;
    } 
}
  • Вы не обрабатываете '#' как первый символ (или дополнительный '#').
  • S[i+1] выходит за границы, когда i == S.size() - 1
  • ваш i += 2 выполняется в дополнение к обычному ++i.

Ваш код может быть упрощен с помощью:

std::string backspace_string_simplification(const std::string& s)
{
    std::string res;

    for (char c : s) {
        if (c != '#') {
            res.push_back(c);   
        } else if (!res.empty()) {
            res.pop_back();   
        }
    }
    return res;
}

Демонстрация

Затем ваше «сравнение строк»:

bool x;
if (a.size() == 0)
    x = true;
else {
    for(int i = 0; i < a.size(); i++) {
        if(a[i]==b[i]) x = true;
        else x = false;
    }
}
return x;
  • , когда a пусто, строка равна, если b тоже пусто.
  • , если размер a и b отличается, у вас либо нет доступа в l oop, либо вы игнорируете оставшееся сравнение (тогда как оно должно быть ложным).
  • ваш if в l oop эквивалентен x = (a[i] == b[i]), поэтому ваш l oop эквивалентен (с правильным размером) x = a.back() == b.back().

You может просто сделать return a == b; (либо std::string и std::vector<char> обработать это).

в результате

bool backspaceCompare(string lhs, string rhs) {
    return backspace_string_simplification(lhs) == backspace_string_simplification(rhs);
}
...