|
@@ -9,10 +9,10 @@ Even a stupid problem can lead to some thoughts.
|
|
|
authors = ["xry111"]
|
|
|
+++
|
|
|
|
|
|
-{{% alert note %}}
|
|
|
+{{% callout note %}}
|
|
|
本文中对 C 语言标准章节的引用以 [N1570][N1570] 为准。
|
|
|
[N1570]:/assets/std/c1x-n1570.pdf
|
|
|
-{{% /alert %}}
|
|
|
+{{% /callout %}}
|
|
|
|
|
|
# 某笔试题中的未定义行为
|
|
|
|
|
@@ -196,14 +196,14 @@ CPU 可能会直接预取 `array` 减 1 后指向的那个地址,
|
|
|
就算是在普通的笔记本上,编译器看到这句话也可以做任何事,
|
|
|
包括在你的屏幕上输出 `I am angry!`.
|
|
|
|
|
|
-{{% alert note %}}
|
|
|
+{{% callout note %}}
|
|
|
再强调一次,这不是说 `array-1` 的结果没有意义,
|
|
|
而是说表达式 `array -= 1` **本身** 没有意义,
|
|
|
这导致 **任何** 执行它的程序流程 **都** 没有意义。
|
|
|
理论上它可能表现为 `system("mkfs.ext4 /dev/sda1")`,
|
|
|
`raise(SIGBUS)`,
|
|
|
甚至 `__builtin_unreachable()`。
|
|
|
-{{% /alert %}}
|
|
|
+{{% /callout %}}
|
|
|
|
|
|
所以说唯一可行的办法是多分配一个整数的内存空间:
|
|
|
|
|
@@ -226,11 +226,11 @@ array = calloc(u_size, sizeof(int));
|
|
|
这里连乘法溢出的判断都交给 `calloc` 进行了,
|
|
|
但是传递参数时仍要检查是否会发生截断。
|
|
|
|
|
|
-{{% alert note %}}
|
|
|
+{{% callout note %}}
|
|
|
据报道,某些老旧的 C 运行库没有在 `calloc` 中判断乘法溢出。
|
|
|
(这类运行库曾经引起一系列安全问题。)
|
|
|
如果你希望程序能在这些违反标准的环境下工作,需要自行判断乘法溢出。
|
|
|
-{{% /alert %}}
|
|
|
+{{% /callout %}}
|
|
|
|
|
|
然而,无论是 `malloc` 还是 `calloc` 分配失败的时候都会返回 `NULL`
|
|
|
(7.22.3.2p3, 7.22.3.4p3),如果解引用空指针,又会产生未定义行为,
|