C : Splint pointers related warnings. 它们是什么意思?

标签 c pointers memory-leaks splint

以下代码编译和执行时没有任何警告或错误。但是,当我使用 splint分析代码,它显示了 4 个警告(显示在代码下方)。

我见过的大多数示例(带有此类警告)都使用 malloc 和 free。由于此代码不使用 malloc,我们可以说忽略这些警告是安全的吗?在不删除指针的情况下编写此代码的正确方法应该是什么?

#include <stdio.h>

typedef struct
{
    void (*Doit) ( void );
} func;

typedef struct
{
    func f;
    int val;
} obj;

typedef struct
{
    obj *o;
} world;

static void Read( void ) {
    printf( "Read\n");
}

static void Init( world *w ) {
    obj pc;
    w->o = &pc;           //(1)
    w->o->val = 10;
    w->o->f.Doit = Read;
    w->o->f.Doit();
}

int main() {
    world w;
    Init( &w );     //(2)
    return 0;      //(3)
}

(1) :28:5: Implicitly only storage w->o (type obj *) not released before assignment: w->o = &pc . A memory leak has been detected. Only-qualified storage is not released before the last reference to it is lost.

(1) :28:5: Immediate address &pc assigned to implicitly only: w->o = &pc . An immediate address (result of & operator) is transferred inconsistently.

(2) :33:11: Variable w used before definition An rvalue is used that may not be initialized to a value on some execution path.

(3) :34:14: Only storage w.o (type obj *) derived from variable declared in this scope is not released (memory leak). A storage leak due to incomplete deallocation of a structure or deep pointer is suspected. Unshared storage that is reachable from a reference that is being deallocated has not yet been deallocated. Splint assumes when an object is passed as an out only void pointer that the outer object will be deallocated, but the inner objects will not.

这段代码只是对我想实现的其他东西的测试,但由于我不精通C,所以我想了解使用上述方法的内存泄漏风险。

提前致谢。

最佳答案

我发现 splint 输出非常难读。根据您的平台,您可能还想尝试 valgrind

无论如何,您的代码的主要问题是 pc 是局部变量。 它在 Init() 结束时变得无效,因为它(可能对于每个编译器)位于堆栈中。

你可能会想做

w->o = (obj *) malloc(sizeof(obj));

相反。

另一种方法是将 w 中 o 的类型更改为 obj 而不是 obj *

注意 C 中的内存管理(强烈推荐进一步阅读):

函数参数和局部变量通常位于所谓的中。一旦函数返回,它们就会失效。 编译器始终需要知道堆栈对象的大小。

通过 malloc() 分配的对象位于堆上。 malloc() 可用于未知大小的对象。由 malloc() 分配的对象在其指针传递给 realloc()free() 之前保持有效。如果您忘记将 malloc 指针传递给 free,就会发生内存泄漏。如果您在对象变为无效后访问它,您将得到未定义的行为(堆中的那个位置现在可能被其他东西重用,但也许数据仍然存在,谁知道呢?)。在最坏的情况下,您可能会遇到段错误或堆损坏。如果您将无效的对象指针传递给 free()realloc(),您可能会遇到堆损坏。

全局变量和静态函数成员位于其他地方 (tm),并且在整个程序执行期间有效(至少从进入 main 直到从它返回,就像 main 的局部变量)。

malloc() 是一个复杂的函数,它在内部管理称为堆的复杂数据结构中的可用内存块。堆损坏意味着您损坏了该数据结构本身。段错误意味着您在有效内存块之外的某处写入/读取。

请注意,C 标准不保证任何情况。它不能保证像堆栈这样的东西甚至存在。但是,我所知道的所有编译器都是这样做的。不过,对于某些嵌入式平台,malloc() 是一个非常简单的函数,每次分配内容时只会递增一个指针,而 free() 什么都不做。

关于C : Splint pointers related warnings. 它们是什么意思?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22777076/

相关文章:

c - 取消引用指向结构的指针以访问其第一个成员

c - 指向 c 中的数组的指针不起作用

memory-leaks - jemalloc 堆分析仅跟踪分配吗?

memory-leaks - ANTLR4内存清理

c - C 什么时候决定 char[] 是字符数组还是字符串?

c - 切换数据类型 int 的第 100 位会产生意想不到的结果

c - 为什么在函数声明中传递 const 指针参数无效

javascript - 我需要更多关于 Puppeteer page.metrics 和 queryObjects 的信息

c - 这里有什么问题?以及如何修复它

c - 下面的代码片段产生相同的输出。但哪个是正确的呢?