C++神奇错误之 bool 与垃圾值

inline 的玄学妙用

Posted by TH911 on August 4, 2025

参见此处

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
//#include<bits/stdc++.h>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<iomanip>
#include<cstdio>
#include<string>
#include<vector>
#include<cmath>
#include<ctime>
#include<deque>
#include<queue>
#include<stack>
#include<list>
using namespace std;
constexpr const int N=1000,M=1000,P=M,inf=0x3f3f3f3f;
int n,m,p,a[N+1][M+1],cost[N+1];
int dp[2][N+1][P+1];
int node(int x){
	x--;
	x%=n;
	if(x<0){
		x+=n;
	}
	x++;
	return x;
}
int max(int a,int b){
	if(a>b){
		return a;
	}
	return b;
}
int main(){
	/*freopen("test.in","r",stdin);
	freopen("test.out","w",stdout);*/
	
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	
	cin>>n>>m>>p;
	for(int i=1;i<=n;i++){
		for(int j=1;j<=m;j++){
			cin>>a[i][j];
		} 
	}
	for(int i=1;i<=n;i++){
		cin>>cost[i];
	}
	bool mode;
	for(int i=1;i<=m;i++){
		mode=!mode;
		int Max;
		if(i==1){
			Max=0;
		}else{
			Max=-inf;
		}
		for(int j=1;j<=n;j++){
			for(int k=0;k<i-1&&k<p;k++){
				Max=max(Max,dp[!mode][j][k]);
			}
		}
		for(int j=1;j<=n;j++){
			dp[mode][j][0]=Max-cost[j]+a[j][i];
			for(int k=1;k<i&&k<p;k++){
				dp[mode][j][k]=dp[!mode][node(j-1)][k-1]+a[j][i];
			}
		}
	}
	int ans=dp[mode][1][0];
	for(int i=1;i<=n;i++){
		for(int j=0;j<m&&j<p;j++){
			ans=max(ans,dp[mode][i][j]);
		}
	}
	cout<<ans<<'\n';
	
	cout.flush();
	 
	/*fclose(stdin);
	fclose(stdout);*/
	return 0;
}

滚动数组下标为 bool mode;

注意到 bool 占用了 $1\text{Byte}$,但是有用的只有一位。剩下 $7$ 位均为垃圾值,因此会出现:

可以发现,bool 存储了一个 $30$。

事实上,bool! 运算仅操作一位

这一点非常坑人,因为其余类型(intshortchar)的 ! 都是整体取 !


因此,开头的代码会 RE,因为 mode 可能是大于 $1$ 的数。


当然,这取决于编译器的实现,是 UB,不要这么写。测试环境 C++14(GCC 9.3.0)。