我有一个如下代码:
struct abc
{
int *xyz;
}
void func1(abc *ptr, .... lots of other struct ptrs passed)
{
func2(ptr->xyz) // some computation, only read from ptr->xyz
...
...
func3(ptr->xyz) // some computation, ptr->xyz is only read
}
void main()
{
abc *ptr;
// memory is allocated properly here for ptr and ptr->xyz.
func1(ptr,...);
}
问题:由于ptr->xyz=0x0,func3发生Seg故障。直到func2,ptr->xyz地址是正确的。在func3之前没有其他相关代码。不可复制。核心转储中没有太多关于内存损坏或valgrind开始的信息。
分析:我运行了GDB,并在正常工作情况下使用了awatch*命令(ptr->xyz的地址)。在整个func1,func2,func3中,我们只读取ptr->xyz内存地址。在正常工作场景中,不会发生写操作。所以我相信这可能是由于其他一些内存损坏重叠造成的。
问题:如果我作为void func1(const-abc*const-ptr)传递。我不想更改abc或abc->xyz的地址/数据。"const"是否确保结构abc,abc->xyz始终存储在内存中的某个只读段中,从而避免任何内存损坏?可能是由于其他结构内存地址重叠写入?
谢谢!
"const"是否确保结构abc,abc->xyz始终存储在内存中的某个只读段中,从而避免任何内存损坏?
不,不是总是。使用const
,如果代码有意修改变量,则在编译时会发出诊断(警告/错误)。
如果试图通过使用具有非常量限定类型的左值来修改使用常量限定类型定义的对象,则行为是未定义的。C11§6.7.3 6
如果代码在运行时尝试修改const
变量,它可能会工作,可能会静默失败,可能会使程序崩溃。这是未定义的行为。
在OP的情况下,可疑代码正在越界写入字段xyz
,因此使xyz
成为const
并没有多大帮助。