《程序员面试金典》5.4位操作题负数左移UB及LeetCode报错咨询
《Cracking the Coding Interview》5.4题相关UB与代码错误问题
我正在尝试解答《Cracking the coding interview:189 programming questions and solutions,fifth edition》中的第5.4题,题目内容如下:
给定一个正整数,打印其二进制表示中1的位数相同的下一个更小和下一个更大的数。
Stack Overflow上存在完全相同的同类问题,但对应答案全部存在错误。我的提问目的是理解代码无法通过UB检查器的原因,而非仅获取解题思路。
问题1:LeetCode报错与编译告警相关
- LeetCode上的「last executed input」是什么含义?是否是触发错误的输入样例?如果是的话,为什么我开启所有
-Wall编译参数后,三款编译器都没有给出对应告警?
问题2:原书代码UB错误原因
原书给出的代码如下:
class Solution { public: int getNext(int n) { int c = n; int c0 = 0; int c1 = 0; while (((c & 1) == 0) && (c != 0)) { c0++; c >>= 1; } while ((c & 1) == 1) { c1++; c >>= 1; } if (c0 + c1 == 31 || c0 + c1 == 0) { return -1; } int p = c0 + c1; n |= (1 << p); n &= ~((1 << p) - 1); n |= (1 << (c1 - 1)) - 1; return n; } int getPrev(int n) { int temp = n; int c0 = 0; int c1 = 0; while ((temp & 1) == 1) { c1++; temp >>= 1; } if (temp == 0)return -1; while (((temp & 1) == 0 )&& (temp != 0)) { c0++; temp >>= 1; } int p = c0 + c1; n &= ((~0) << (p + 1)); int mask = (1 << (c1 + 1)) - 1; n |= mask << (c0 - 1); return n; } vector<int> findClosedNumbers(int num) { int m = getNext(num); int n = getPrev(num); return {m,n}; } };
运行报错输出如下:
Line 43: Char 14: runtime error: left shift of negative value -1 (solution.cpp) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:53:14
我已查询到相关资料说明左移负数属于未定义行为(Undefined Behavior, UB),但我在godbolt上开启了所有能想到的-Wall相关参数都没有收到告警,是否有类似UndefinedBehaviorSanitizer的编译参数可以检测这类问题?
问题3:社区Stack Overflow答案栈溢出原因
社区某Stack Overflow答案的代码无法通过LeetCode测试,对应代码如下:
class Solution { public: vector<int> findClosedNumbers(int num) { int m = getNextLarger(num); int n = getNextSmaller(num); return { m,n }; } int getNextLarger(int num) { if (num == 0 || num == -1) return num; // (1) add 1 to the last set bit int largeNum = num + (num & ~(num - 1)); // (2) move the changed bits to the least significant bits. (right side) int flipBits = num & ~largeNum; int lastBits = 0; while (flipBits != 0) { flipBits &= flipBits - 1; lastBits <<= 1; lastBits |= 1; } lastBits >>= 1; // (2.1) move bits to maintain the same number of set bits. largeNum |= lastBits; return largeNum; } //Unhandled exception at 0x0033F4B9 in leetcode.exe: 0xC00000FD: Stack overflow int getNextSmaller(int num) { //with num=2 return ~getNextLarger(~num); } };
该代码在输入num=2时会触发栈溢出异常,请问存在什么问题?
内容的提问来源于stack exchange,提问作者mingyEx
相关产品推荐
相关产品推荐

