【问题标题】:ERROR: AddressSanitizer: negative-size-param: (size=-1)错误:AddressSanitizer:负大小参数:(大小=-1)
【发布时间】:2020-07-22 07:33:49
【问题描述】:

很抱歉这段乱​​七八糟的代码,但我有一个问题。

我试图解决 LeetCode 的 844 任务。鉴于此

给定两个字符串 S 和 T,如果它们在空文本编辑器中键入时相等,则返回。 # 表示退格字符。


第一个例子

输入:S = "ab#c", T = "ad#c"
输出:真
解释:S和T都变成“ac”。

第二个例子

输入:S = "ab##", T = "c#d#"
输出:真
解释: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 位于 1 字节区域右侧 0 字节 [0x602000000150,0x602000000151)
此处由线程 T0 分配:
#5 0x7f585c70d82f (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
==32==正在中止

但它给了我这样的错误。我认为这里的一切都很好。我的错在哪里?

【问题讨论】:

  • 假设# 是字符串的第一个字符,你的代码要做什么?
  • 你应该创建函数来简化字符串,而不是重复的逻辑。
  • @NathanOliver 但是我的代码在这个 ("ab##" "c#d#") 案例中失败了。
  • 您的比较函数也是错误的,因为 x 仅依赖于最后一个字符比较。 return a == b; 应该可以完成这项工作。

标签: c++ address-sanitizer


【解决方案1】:

您的代码中有几个问题

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;
    } 
}
  • 您不将'#'作为第一个字符(或额外的'#')处理。
  • i == S.size() - 1 时,S[i+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;
}

Demo

然后,你的“字符串比较”:

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 也为空,则字符串相等。
  • 如果ab 的大小不同,则您要么在循环中有越界访问,要么忽略剩余的比较(而它应该为假)。
  • 循环中的if 等同于x = (a[i] == b[i]),因此您的循环等同于(大小正确)x = a.back() == b.back()

您可以简单地执行 return a == b;std::stringstd::vector&lt;char&gt; 处理)。

导致

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

【讨论】:

    猜你喜欢
    • 2016-09-14
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多