【问题标题】:Insert values to struct members through pointer of type struct通过 struct 类型的指针向 struct 成员插入值
【发布时间】:2015-02-19 17:20:21
【问题描述】:

我不明白指针和结构之间的关系;为什么如果我尝试通过 struct 类型的指针访问 struct 成员,并使用指针给它们值,我会得到分段错误??

如果我将结构指针声明为:

typedef struct a {
int b;
}A;

int main(){
A *ptr;
}

我可以使用这种语法访问结构成员

(*ptr).b or ptr->b

即使 ptr 不指向任何内容,ptr 也可以访问 struct 成员,因为 ptr 被声明为 struct 类型,对吧??

如果我没有显式设置指针指向某处,指针一般指向他的类型,在这种情况下A没有??

但是当我尝试通过指针给结构成员一些值时,我总是遇到分段错误

ptr->b=9;

【问题讨论】:

  • 通过无效指针访问元素在语法上是正确的,因此它通过了编译。但是,它会在运行时导致未定义的行为。行为符合预期。
  • 如果您不将指针指向某物,则它是未定义的行为。它崩溃并不奇怪。

标签: c


【解决方案1】:

变量 ptr 可用于访问结构成员,如果 ptr 未指向正确类型的结构,则可能会发生坏事(这种坏事的技术术语是未定义行为)。通常是程序因错误而终止、程序做错事或程序似乎做正确的事之一,不太常见的结果包括“匿名”利用您的错误关闭您的业务。

如果指针没有设置为指向某个地方,它(通常)指向其他地方,(它总是指向某个地方),类型没有可以指向的位置,类型是指针的属性,而不是它指向的位置的属性,如果你想使用它,你必须将它指向正确的位置。

分段错误是未定义行为的常见示例。

【讨论】:

    【解决方案2】:

    您告诉编译器 - 请在堆栈 A *ptr; 上创建它,它确实这样做了 - 但您没有分配任何内存(从堆中)或将其分配给某个变量

       --------------> Points to where ??
    | ^ |
     /
    ptr
    

    然后您尝试像 *ptr 那样取消引用它-您没有对其进行初始化-因此它有权将您带到任何可能的地方-因此称为未定义行为。 你的编译器应该带你去哪里?

    你应该做的:

    A *ptr = malloc(sizeof(A)); 
    

    A a1;
    A *ptr = &a1; 
    
    
       ------------------> Points to   |  |
    | ^ |                            a1/
     /
    ptr
    

    【讨论】:

      【解决方案3】:

      即使 ptr 不指向任何内容,ptr 也可以访问 struct 成员,因为 ptr 被声明为 struct 类型,对吧?

      为什么会这样?指针只是指向某个地方; 某处不一定是内存中的有效位置。

      char* p = (char*)0x12345678; // Syntactically valid; not a real place in memory!
      

      指针不分配除sizeof(void*) 字节以外的任何内存来保存实际地址。

      由于ptr 只是一个指针,而不是一个实际的结构对象,因此在任何地方都没有分配A 结构,因此出现了段错误。

      A someA;
      A* ptr;
      (*ptr).b = 9; // or...
      ptr->b = 9;
      

      以上是正确的用法。

      【讨论】:

      • 但是例如,如果我声明一个指针,如:int *ptr,它应该指向一个 int no 吗?
      猜你喜欢
      • 1970-01-01
      • 2017-11-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多