【问题描述】
LeetCode第18题. 四数之和报错“栈溢出”。
这道题目中共遇到两类报错。
class Solution
{
public:
vector<vector<int>> fourSum(vector<int>& nums, int target)
{
vector<vector<int>> result;
sort(nums.begin(), nums.end()); // 升序排列
for(int a = 0; a < nums.size(); a++)
{
if(nums[a] > target && nums[a] >= 0)
{
break; // 结束循环
}
if(nums[a] == nums[a-1] && a > 0)
{
continue; // 去重
}
for(int b = a+1; b < nums.size(); b++)
{
if(nums[a] + nums[b] > target && nums[a] + nums[b] >= 0)
{
break;
}
if(nums[b] == nums[b - 1] && b > a + 1)
{
continue;
}
int c = b + 1;
int d = nums.size() - 1;
while(c < d)
{
if(nums[a] + nums[b] + nums[c] + nums[d] > target)
{
d--;
}
else if(nums[a] + nums[b] + nums[c] + nums[d] < target)
{
c++;
}
else{
result.push_back(vector<int> {nums[a], nums[b], nums[c], nums[d]});
while(d > c && nums[d] == nums[d - 1]) d--;
while(d > c && nums[c] == nums[c + 1]) c++;
c++;
d--;
}
}
}
}
return result;
}
};
上面这段代码执行出错,
Line 1037: Char 34: runtime error: addition of unsigned offset to 0x503000000070
overflowed to 0x50300000006c (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/11/../../../../include/c++/11/bits/stl_vector.h:1046:34
这个问题很常见,就是访问到非法内存,一般就是数组越界了。
在这里,if(nums[a] == nums[a-1] && a > 0)
,试图去访问nums[-1]了。所以应该将 a > 0
的条件放在前面。
这里改完之后继续报错,
Line 34: Char 56: runtime error: signed integer overflow: 2000000000 + 1000000000 cannot be represented in type 'value_type' (aka 'int') (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:43:56
在计算机中,整数类型(如int、long等)有一定的取值范围。当进行加法运算时,如果两个整数的和超过了该类型的取值范围,就会发生溢出,导致结果不正确。
为了避免这种情况,可以使用强制类型转换将其中一个或多个操作数转换为更大的整数类型,以确保运算过程中不会发生溢出。
所以我们在nums[k]前面加一个 (long)
,将其强制转换成 long 类型。