I am not able to find where is my vector going out of bound. This is solution of leetcode question 695.
Error:
Line 1034: Char 34: runtime error: addition of unsigned offset to 0x610000000040 overflowed to 0x610000000028 (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:34
Code:
int maxAreaOfIsland(vector<vector<int>>& grid) {
int n = grid.size();
int m = grid[0].size();
vector<vector<int>> vis(n,vector<int>(m,0));
int ans =0 ;
for(int i=0;i<n;i++) {
for(int j=0;j<m;j++) {
int count = 0;
if(grid[i][j]==1 && !vis[i][j]) {
vis[i][j]=1;
queue<pair<int,int>> q;
q.push({i,j});
count++;
while(!q.empty()) {
int a = q.front().first;
int b = q.front().second;
q.pop();
int r[] = {-1, 1, 0, 0};
int c[] = {0, 0, 1, -1};
for(int z=0; z<4; z++) {
int x = a + r[z];
int y = b + c[z];
if(x<n && y<m && grid[x][y]==1 && !vis[x][y]) {
vis[x][y]=1;
q.push({x,y});
count++;
}
}
}
ans = max(ans,count);
}
}
}
return ans;
}
I expect
if(x<n && y<m && grid[x][y]==1 && !vis[x][y]) {
should be
if (x>=0 && y>=0 && x<n && y<m && grid[x][y]==1 && !vis[x][y]) {
Notice in the error addition of unsigned offset to 0x610000000040 overflowed to 0x610000000028. In other words the unsigned offset is negative (when regarded as a signed quantity).
Always be careful mixing signed and unsigned arithmetic.
I am not able to find where is my vector going out of bound
The simplest way(IMO) to find out where you're going out of bounds in the vector is to use std::vector::at instead of std::vector::operator[].
When using at you'll get an out_of_range exception if the index is greater or equal to the size of the vector. For example, use grid.at(i).at(j) instead of grid[i][j] and so on for other as well.
Related
I was solving the famous leetcode question 4sum and I came up with an optimal solution but I am facing an integer overflow even though I have used long long int datatype.
class Solution {
public:
vector<vector<int>> fourSum(vector<int>& nums, int target) {
vector<vector<int>> res;
if(nums.empty()){
return res;
}
int n = nums.size();
sort(nums.begin(), nums.end());
for(int i=0; i<n; i++){
for(int j=i+1; j<n; j++){
long long int temp = target - (nums[j] + nums[i]);
int front = j+1;
int back = n-1;
while(front < back){
long long int twosum = nums[front] + nums[back];
if(twosum < temp){
front++;
}
else if(twosum > temp){
back--;
}
else{
vector<int> ans(4,0);
ans[0] = (nums[i]);
ans[1] = (nums[j]);
ans[2] = (nums[front]);
ans[3] = (nums[back]);
res.push_back(ans);
while(front < back && nums[front] == ans[2]) ++front;
while(front < back && nums[back] == ans[3]) --back;
}
}
while(j+1 < n && nums[j+1] == nums[j]) ++j;
}
while(i+1 < n && nums[i+1] == nums[i]) ++i;
}
return res;
}
};
Here is the error message:
Line 12: Char 41: runtime error: signed integer overflow: -294967296 - 2000000000 cannot be represented in type 'int' (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:21:41
Although in this compound statement
long long int temp = target - (nums[j] + nums[i]);
the destination variable temp is of sufficient size, the actual arithmetic happens on the types determined from integer promotion rules, applied to target and nums, both of which are of just int.
You'll have to upcast them to a sufficiently large type before the arithmetic operator takes effect. Like this
long long int temp = (long long int)target - ((long long int)nums[j] + (long long int)nums[i]);
I am trying to solve leetcode problem 200. Number of Islands and I am getting this error Line 1034: Char 34: runtime error: addition of unsigned offset to 0x6020000000d0 overflowed to 0x6020000000cf (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:34
class Solution {
public:
int numIslands(vector<vector<char>>& grid) {
if(grid.size() == 0) return 0;
int r = grid.size();
int c = grid[0].size();
vector<vector<int>>vis(r,vector<int>(c,0));
int islands = 0;
for(int i =0 ;i<r;i++){
for(int j =0 ;j<c;j++){
if(grid[i][j]=='1' && vis[i][j]==0){
bfs(i,j,grid,vis);
islands++;
}
}
}
return islands;
}
void bfs(int i ,int j,vector<vector<char>>& grid,vector<vector<int>>&vis){
deque<pair<int,int>>q;
q.push_back({i,j});
vis[i][j]=1;
while(!q.empty()){
int row = q.front().first;
int col = q.front().second;
q.pop_front();
vector<pair<int,int>> directions = {{1,0},{-1,0},{0,1},{0,-1}};
for( auto dir: directions){
int r = row+dir.first;
int c = col+dir.second;
if((r>=0 && r<grid.size()) && (col>=0 && col<grid[0].size()))
{
if(grid[r][c] == '1' && vis[r][c] == 0){
q.push_back({r,c});
vis[r][c]=1;
}
}
}
}
}
};
But this code is working fine in my local compiler. Can anyone please guide me about what have I done wrong here?
I'm getting an heap corruption error and I can't figure out where it is.
The problem is a coin change problem using dynamic programming. C is the array with the coin values, n is the size of the array, T is the target change, usedCoins is an array where the number of used coins should be mapped (i.e if C[1] = 2 and 3 2-coins are used, usedCoins[2] = 2 with all other indexes to 0.
Here's the code:
bool changeMakingUnlimitedDP(unsigned int C[], unsigned int n, unsigned int T, unsigned int usedCoins[]) {
static auto minCoins = new unsigned int[T+1]{UINT_MAX};
minCoins[0] = 0;
static auto lastCoin = new unsigned int[T+1]{0};
for(int i = 0; i < n; i++)
usedCoins[i] = 0;
for(int i = 0; i < n; i++){
for(int j = 1; j <= T; j++){
if(j >= C[i]){
minCoins[j-C[i]] == 0? minCoins[j] = 1 : minCoins[j] = std::min(1 + minCoins[j - C[i]], minCoins[j-C[i]]);
lastCoin[j] = i;
}
}
}
while(T > 0){
unsigned int last = lastCoin[T];
if(last == UINT_MAX || last < 0) return false;
usedCoins[last]++;
T -= C[last];
}
free(minCoins);
free(lastCoin);
return true;
}
When running on debug mode it goes through.
Can anyone please explain how to deal with run time error?
Line 1034: Char 34: runtime error: addition of unsigned offset to 0x607000000020 overflowed to 0x607000000018 (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:34
Code fiddle
class Solution {
public:
static bool cmp(pair<int,int> a, pair<int,int> b){
if(a.first<b.first) return true;
if(a.first==b.first && a.second>b.second) return true;
return false;
}
vector<int> frequencySort(vector<int>& nums) {
int n = nums.size();
vector<int> res;
vector<pair<int,int>> v(n);
for(int i = 0;i<n;i++){
v[nums[i]].first++;
v[nums[i]].second = nums[i];
}
sort(v.begin(),v.end(),cmp);
for(int i =0;i<n;i++){
for(int j =0;j<v[i].first;j++){
res.push_back(v[i].second);
}
}
return res;
}
};
There're 2 problems:
nums[i] is between -100 and 100. The vector v can't handle this case. This could be fixed easily with an offset of 100.
vector<pair<int,int>> v(n);. Remember, this is a vector of frequency. It can't handle case like, for example, n = 5 but num[i] reach 50 or 100. This can also be fixed with a different const resize.
New code:
static bool cmp(pair<int,int> a, pair<int,int> b){
if(a.first<b.first) return true;
if(a.first==b.first && a.second>b.second) return true;
return false;
}
const int offset = 100;
const int sz = 201; //because with an offset of 100, nums[i] could reach max 100+100=200
vector<int> frequencySort(vector<int>& nums)
{
int n = nums.size();
vector<int> res;
vector<pair<int,int>> v(sz);
for(int i = 0;i<n;i++){
v[nums[i]+offset].first++;
v[nums[i]+offset].second = nums[i]+offset;
}
sort(v.begin(),v.end(),cmp);
for(int i =0;i<sz;i++){
for(int j =0;j<v[i].first;j++){
res.push_back(v[i].second-offset);
}
}
return res;
}
P.S: When doing programming problems, you should check the constraint:
1 <= nums.length <= 100
-100 <= nums[i] <= 100
and testcases. In this problem, the case:
Input: nums = [-1,1,-6,4,5,-6,1,4,1]
Output: [5,-1,4,4,-6,-6,1,1,1]
that Leetcode provide could help you debug quicker.
Observing a runtime error when trying to run the below code !!
Line 1034: Char 9: runtime error: reference binding to null pointer of type 'int' (stl_vector.h)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior /usr/bin/../lib/gcc/x86_64-linux-gnu/9/../../../../include/c++/9/bits/stl_vector.h:1043:9
#include <algorithm>
#include <climits>
#include <vector>
class Solution {
public:
int minimumTotal(vector<vector<int> > &triangle) {
vector< vector<int> > soln(1000, vector<int>(0)) ;
vector< vector<int> > index(1000, vector<int>(0)) ;
int ans = INT_MIN ;
int tmp = 0;
int ind = 0;
soln[0][0]=triangle[0][0];
index[0][0]=0;
int triangle_size = int(triangle.size());
for (int i = 1 ; i < triangle_size ; i++) {
int soln_size = int(soln[i-1].size());
for (int j = 0; j < soln_size ; j=j+2) {
ind = index[i-1][j];
tmp = soln[i-1][j] + triangle[i][ind];
if (tmp > ans) {
ans=tmp;
}
soln[i][j] = tmp;
index[i][j] = ind;
tmp = soln[i-1][j] + triangle[i][ind+1];
if (tmp > ans) {
ans=tmp;
}
soln[i][j+1] = tmp;
index[i][j+1] = ind+1;
}
}
return ans;
}
};
int minimumTotal(vector<vector<int> > &triangle) {
vector< vector<int> > soln(1000, vector<int>(0)) ;
vector< vector<int> > index(1000, vector<int>(0)) ;
int ans = INT_MIN ;
int tmp = 0;
int ind = 0;
>>>> soln[0][0]=triangle[0][0]
>>>> index[0][0]=0;
Here. soln is a vector of 1000 vector of size 0, soln[0] is a vector of size 0, so soln[0][0] is out of range. Accessing it is a UB.