gpt4 book ai didi

objective-c - 为什么 C 编译器不警告 malloc 大小错误?

转载 作者:太空宇宙 更新时间:2023-11-04 01:22:06 26 4
gpt4 key购买 nike

我在我的 iOS 应用程序的 ViewDidLoad 中创建了一个成员结构。我使用 malloc 为这个结构分配空间,然后在我的类里面使用它。像这样:

self.myData = malloc(sizeof(MyData));

除了我真正做的是这样的:

self.myData = malloc(sizeof(MyOtherStruct));

我不小心将 malloc 调用中的 sizeof() 设置为不同的结构(大小不同)。我很长一段时间都没有注意到这个错误,因为应用程序很少崩溃。操作系统更新导致崩溃更频繁地发生。

我的问题是,为什么编译器不能对这类事情发出警告?这是编译器不知道的事情,还是允许用户 malloc 任意大小的设计选择?

最佳答案

“我怎样才能更快地找到这个错误?”

有很多方法可以更快地找到错误。

解决方案 #1

静态分析器发现了这个错误。在 Xcode 中按 command-shift-B。例如,采用以下代码:

#include <stdlib.h>

struct x { double x; };
struct y { char y; };

int main(int argc, char **argv) {
struct x *p = malloc(sizeof(struct y));
p->x = 1.0;
return 0;
}

运行分析器会为我产生这个错误:

Result of 'malloc' is converted to a pointer of type 'struct x' which is incompatible with sizeof operand type 'struct y'

解决方案 #2

建议改为这样写代码:

self.myData = malloc(sizeof(*self.myData));

以后就这样吧。这不仅不容易出错,而且更容易记住。

解决方案 #3

使用 Swift 或 C++ 等语言,其中语言的类型系统可帮助您避免此类错误。 C 在很多方面都不那么宽容。它是在 1970 年代早期发明的,如果你想使用它,你就必须接受它,而这些错误是 C++ 和 Swift 甚至存在于世界中的主要部分原因第一名。

解决方案 #4

使用运行时内存边界检查器,例如地址清理器。这将在访问内存时检测到错误,而不是在分配内存时检测到错误,但它仍然会为您提供访问和分配的堆栈跟踪(如果内存已被释放,则释放)。现在写 C 的任何人都应该熟悉地址 sanitizer 及其 friend tsan、ubsan 等。

Valgrind 也能达到相同的效果,但地址 sanitizer 对于常见用例具有更好的用户体验。

如题

编译器实际上只给你错误和类型错误的警告。这不是类型错误,而是运行时错误。编译器可以检测到一些“可能的”运行时错误,但数量很少。诸如忘记使用 malloc() 的返回值之类的事情......例如,

void f(void) {
malloc(1); // warning
}

编译器并不比那好多少。

同样,这是 C++ 和 Swift 等较新语言的插入力,它们的类型系统允许您在分配不当时产生错误,这也是静态分析(这是一个棘手的问题)的插入力。

关于objective-c - 为什么 C 编译器不警告 malloc 大小错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39866908/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com