What does AddressSanitizer: SEGV on unknown address 0x000000000000 mean?

Viewed 28982

I'm solving a leetcode question and getting this error. I have no idea what this mean as I'm relatively new to C++. It appears to disappear when I remove the else inside the else if.

AddressSanitizer:DEADLYSIGNAL
=================================================================
==32==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000383e8c bp 0x7ffc55bebe50 sp 0x7ffc55bebd20 T0)
==32==The signal is caused by a READ memory access.
==32==Hint: address points to the zero page.
    #3 0x7f2222e3982f  (/lib/x86_64-linux-gnu/libc.so.6+0x2082f)
AddressSanitizer can not provide additional info.
==32==ABORTING

My code:

class Solution {
public:
    bool isValid(string s) {
        stack<char> stk;
        int flag=1;
        for(int i=0; i< s.length();i++){
            if(s[i]=='('||s[i]=='{'||s[i]=='['){
                stk.push(s[i]);
                flag=0;
            }
            else { //if (s[i]==')'||s[i]=='}'||s[i]==']'){
                if(s[i]==')'&&stk.top()=='('){
                    stk.pop();
                    flag=1;
                }
                 else if(s[i]==']'&&stk.top()=='['){
                    stk.pop();
                    flag=1;
                }
                else if(s[i]=='}'&&stk.top()=='{'){
                    stk.pop();
                    flag=1;
                }
                else
                    return false;
            }
        }
        if(flag==0)
            return false;
        else
            return true;
    }
};
8 Answers

It means that you are dereferencing a null pointer somewhere in your code. gdb would be a better tool to debug this problem. Run gdb program -ex r until it crashes. Then print stacktrace with bt to see what was going wrong.

That is a segmentation fault because of a deref of a null pointer.

My guess is that you are querying the top element of an empty stack (deque). If the container has never been non-empty, it might hold a null pointer.

The documentation for std::deque<..>::back, which is what is called by std::stack<..>::top confirms that this exhibits UB:

Returns reference to the last element in the container.

Calling back on an empty container causes undefined behavior.

I ran your code for the same problem on leetcode and this statement was faulty.

  if(s[i]==') &&stk.top()=='(')

error was removed by with the help of a boundary check.

  if(s[i]==')'&&!stk.empty() &&stk.top()=='(')

Similarly for two other if statements. Now the code is not giving any error's but logic is incorrect somewhere. It is giving wrong results for "([]" testcase.

you need to handle the case where the input string start by any character meant to be poped, for example ')' or '(', because in this case you are poping from and empty stack already.

if(s[i]==')'&&stk.top()=='('){

In the above line before stk.top() check whether the stack is empty or not.....means stk.size()>0.

This will remove the error.

The issue is with the following line and similar lines:

if(s[i]==')'&&stk.top()=='('){

When executing the top method of stack it returns a reference to the top most element of the stack which is not present in your case (Ref: https://www.geeksforgeeks.org/stack-in-cpp-stl/).

So my advice would be to either check this condition before of check it within the if block.

check stk.empty() in else loop first or a better sollution would be -

 if (s.length() < 2 || s[0] == ']' || s[0] == ')' || s[0] == '}')
        {
            return false;
        }

        stack<char> stk;

        for (int i = 0; i < s.length(); i++)
        {
            if (s[i] == '(' || s[i] == '[' || s[i] == '{')
            {
                stk.push(s[i]);
            }
            else
            {
                if (stk.empty()) return false;
                if (s[i] == ')' && stk.top() != '(')
                    return false;
                if (s[i] == ']' && stk.top() != '[')
                    return false;
                if (s[i] == '}' && stk.top() != '{')
                    return false;

                stk.pop();
            }
        }
        return stk.empty();

include !stk.empty() before stk.top() == '('

Related