C:夹板指针相关警告。它们是什么意思?

C:夹板指针相关警告。它们是什么意思?,c,pointers,memory-leaks,splint,C,Pointers,Memory Leaks,Splint,下面的代码编译并执行时没有任何警告或错误。但是,当我使用分析代码时,它显示4个警告(显示在代码下面) 我看到的大多数示例(带有此类警告)都使用malloc和free。由于此代码不使用malloc,我们可以说忽略这些警告是安全的吗?在不删除指针的情况下,正确的编码方法应该是什么 #include <stdio.h> typedef struct { void (*Doit) ( void ); } func; typedef struct { func f;

下面的代码编译并执行时没有任何警告或错误。但是,当我使用分析代码时,它显示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)
}
#包括
类型定义结构
{
无效(*Doit)(无效);
}func;
类型定义结构
{
函数f;
int-val;
}obj;
类型定义结构
{
obj*o;
}世界;
静态无效读取(无效){
printf(“读取\n”);
}
静态void Init(世界*w){
obj-pc;
w->o=&pc;//(1)
w->o->val=10;
w->o->f.Doit=读取;
w->o->f.Doit();
}
int main(){
世界卫生组织;
初始(&w);/(2)
返回0;/(3)
}
(1) :28:5:仅隐式存储w->o(类型obj*)在分配之前未释放:w->o=&pc。检测到内存泄漏。只有合格的存储在最后一次引用丢失之前才会释放

(1) :28:5:仅隐式分配给的即时地址和pc:w->o=&pc。立即地址(运算符的结果)传输不一致

(2) :33:11:定义前使用的变量w使用的右值可能未初始化为某些执行路径上的值

(3) :34:14:只有从该作用域中声明的变量派生的存储w.o(类型obj*)未释放(内存泄漏)。怀疑由于结构或深度指针的未完全释放而导致存储泄漏。可从正在解除分配的引用访问的非共享存储尚未解除分配。Splint假设当一个对象作为仅输出的空指针传递时,外部对象将被释放,而内部对象不会

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


提前感谢。

我发现
夹板的输出非常不可读。根据您的平台,您可能还希望尝试
valgrind

没有reglardles,代码的主要问题是
pc
是一个局部变量。 它在
Init()
的末尾变得无效,因为它(可能每个编译器)都位于堆栈上

你可能会想这样做

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

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

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

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

通过
malloc()
分配的对象位于堆上<代码>malloc()
可用于未知大小的对象。由
malloc()
分配的对象保持有效,直到其指针传递到
realloc()
free()
。如果忘记将
malloc
'd指针传递到
free
,则内存泄漏。如果在对象无效后访问该对象,您将获得未定义的行为(堆中的该位置现在可能被其他对象重新使用,但可能数据仍然存在,谁知道呢?)。在最坏的情况下,可能会出现分段错误或堆损坏。如果将无效的对象指针传递到
free()
realloc()
,可能会导致堆损坏

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

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


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

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

没有reglardles,代码的主要问题是
pc
是一个局部变量。 它在
Init()
的末尾变得无效,因为它(可能每个编译器)都位于堆栈上

你可能会想这样做

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

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

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

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

通过
malloc()
分配的对象位于堆上<代码>malloc()
可用于未知大小的对象。由
malloc()
分配的对象保持有效,直到其指针传递到
realloc()
free()
。如果忘记将
malloc
'd指针传递到
free
,则内存泄漏。如果您在对象无效后访问它,您将获得未定义的行为(堆中的位置可能会被重用)
w->o = (obj *) malloc(sizeof(obj));