结构上的指针算术

Posted

技术标签:

【中文标题】结构上的指针算术【英文标题】:Pointer Arithmetic on structs 【发布时间】:2014-11-11 21:50:28 【问题描述】:

我正在研究一些C代码,当我遇到了以下sn-p:

struct example *example_clone(struct example *ex)
  
    struct example *new_ex;  
    new_ex = ex + 1;    // How does this works ?    
    ....  
    new_ex = some_func(...);  //makes new_ex as struct example
    ....  
  

现在考虑new_ex = ex + 1; new_ex 是在内存中的 ex 之后吗? 如果内存中ex 之后存在其他对象怎么办。换了吗?

【问题讨论】:

使用指针算法,+1 表示 + sizeof(struct example) 如果输入指针ex指向一个结构体数组,那么ex+1指向数组中的下一个结构体。但是如果ex 指向一个单独的结构,那么ex+1 就不会指向任何有用的东西。 new_ex = ex + 1; 表示new_ex = &ex[1]; 【参考方案1】:

该函数应使用struct example 对象的数组来调用。

例如:

struct example bla[2] =  /* initializers */ ;

example_clone(bla);  // OK, bla[1] will be overwritten

这没关系,因为ex + 1 指向一个现有对象。

但是传递一个指向对象而不是数组元素的指针是不行的:

struct example blo =  /* initializers */ ;

example_clone(&blo);  // Not OK, the object at &blo + 1 will be overwritten

这不行,因为ex + 1 不指向现有对象。函数执行将调用未定义的行为。

【讨论】:

【参考方案2】:

1 添加到指针意味着指向下一个元素`。请记住,指针指向特定类型的对象(它们不仅仅是编号的内存位置)。

例如,如果您指向停车场中的第一辆车,那么 +1 表示您指向第二辆车。

如果那里实际上没有其他对象,那很好,C 有一种特殊情况,您可以将一个指向现有对象的末尾。但是如果你再次+1 会导致未定义的行为。

如果您尝试读取该指针并且那里没有对象,则会导致未定义的行为。只要您正在写入分配给您的内存,您就可以通过指针写入。

【讨论】:

【参考方案3】:

new_ex 是否在内存中的 ex 之后?

是的。它指向刚刚超过ex 结尾的内存地址。

如果内存中的 ex 之后存在其他对象怎么办。换了吗?

会发生两件事中的一件。首先,它可以覆盖那里的对象。其次,如果该内存不可用,它可能会出现段错误。出于这个原因,我认为这个功能很危险。我将手动内联此代码,以便您可以验证 ex + 1 的内容/存在。

【讨论】:

以上是关于结构上的指针算术的主要内容,如果未能解决你的问题,请参考以下文章

C 语言结构体 ( 指针运算与指针内存操作 | 结构体成员偏移量计算 )

指针的资源管理之罪

没事抽空学——c语言指针操作基础概念

C++指针的算术运算 关系运算

C 指针的算术运算

C 指针的算术运算