厌氧的代码

P2146 [NOI2015] 软件包管理器

@[YoungL](/user/1050683) 建议看一下您的 `op` 数组开了多少(
by QWQ_123 @ 2024-02-12 16:22:38


@[YoungL](/user/1050683) [改成 char op[10]; 就过了](https://www.luogu.com.cn/record/146729822) 原因: [洛谷变量储存方式](https://www.luogu.com.cn/paste/l8bc1a40) 数组访问越界,开不开 O2 的越界方向恰恰相反,开 O2 恰好越界到了关键的内存位置。
by Terrible @ 2024-02-12 16:28:07


@[Terrible](/user/195942) 已解决,感谢!
by YoungL @ 2024-02-12 16:32:46


更具体原因: 不开 O2 时访问 `op` 越界到 `edges[0]`,`edges[0]` 在全局区的位置储存若干个字节(似乎是 $16$ 个字节?),被 `scanf` 写入后可以正常访问,且后续过程中没有调用 `edges[0]`,因而没出问题。 开 O2 时访问 `op` 越界到 `q`,由于洛谷采用小端序,以及考虑到洛谷评测环境内存采用 `4` 位对齐于是可以得出内存占用情况大致如下: $|\mathrm{op}[0]|\mathrm{op}[1]|\mathrm{op}[2]|\mathrm{op}[3]|\mathrm{op}[4]|{\color{red}\mathrm{op}[5]}|{\color{red}\mathrm{op}[6]}|{\color{red}\mathrm{op}[7]}|\mathrm{q}|\mathrm{q}|\mathrm{q}|\mathrm{q}$ 注:(红色的是为了内存对齐到 $4$ 产生的额外字节;$q$ 是倒着存储的,第一个 $q$ 是储存最低位的字节) 会导致如果读入 `unistall` 那么 `l` 和末尾的 `\0` 会越界到 `q` 的最低位和次低位,从而修改 `q` 的值。 例如 `q=100000=|01|86|a0|`,那么会被修改为 `|01|00|6c|`(16 进制),会减小;也会将 `q=10` 修改成 `q=108`,会增大。 如果减小了,导致很长一段操作内都没有 `uninstall`,以至于 `q=0` 了,进而导致输出减少,会 WA。 如果增大了,因为 `scanf` 读取到流末尾没有东西可以读入的时候,读入的变量内存不会被修改,于是依然保持着原有的状态,而 `x++;` 会让 `x` 稳定的增加 $1$,导致后续的操作内存严重越界从而 RE。
by Terrible @ 2024-02-12 16:55:54


@[Terrible](/user/195942) %%%
by YoungL @ 2024-02-12 20:26:38


@[YoungL](/user/1050683) proooooooo(bushi) ~~一看就是空间炸了~~
by mickey2021 @ 2024-05-19 11:45:14


@[mickey2021](/user/470693) 《char op[5]》 《炸了》
by YoungL @ 2024-05-19 21:16:34


|