【问题标题】:Weird side effect using operator '->' in c在c中使用运算符'->'的奇怪副作用
【发布时间】:2011-08-10 14:29:37
【问题描述】:

在我用 C 编写的代码中使用运算符 '->' 时,我得到了这个奇怪的副作用。我使用 -> on 的指针被更改为有一些垃圾。

更具体地说:

我有以下结构:

typedef void* ListElement ;

typedef  struct List_t* List ;

typedef struct Node_t* Node;

Struct Node_t {
  ListElement data ;
  Node next;
}

Struct List_t {
  Node* head;
  Node* current
}

当我使用以下 ListGetFirst() 时,我得到了有线行为:

ListElement ListGetFirst(List list)
{
  if( list == NULL || list->head==NULL)
  {
    return NULL;
  }
  list->current=list->head;
  Node* head =list->head; // here is the problem
  ListElement data = (*head)->data;
  return data;
}

当我使用调试器时,我发现指针 list->head 在标记的上述行上发生了变化。

我真的不知道为什么,我也不知道'->'会有副作用

提前致谢

【问题讨论】:

  • 您很可能误解了正在发生的事情。
  • 不,-> 在 C 中没有副作用。为什么不直接做return list->head->data
  • 这是您的代码,而不是-> 的“副作用”。这是肯定的。
  • @meagar - 如果这是我的代码,请帮我找到答案,我很绝望
  • 您不应该使用隐藏类型是指针这一事实的 typedef。我们都对此感到困惑!

标签: c pointers linked-list side-effects


【解决方案1】:

你确定这正是你想要做的吗?

typedef struct Node_t* Node;

Node* head =list->head; 

既然您将 Node 定义为指向 Node_t 的指针,您不应该这样做吗:

Node head =list->head; 

编辑

总结一下,我认为这个 typedef 误导了你:

typedef struct Node_t* Node;

如果简单的话会更有意义:

typedef struct Node_t Node;

【讨论】:

  • @karlphillip - 查看结构。我决定在 list_t struct Node* variables 中有,而不是 Node.
  • 我认为卡尔有这个;您使用的是 Node* ,它是指针的地址,而不是作为列表地址的指针值。
  • @RanZilber 你在你的代码上做的事情等价于Node_t** head = list->head;,你显然需要做Node_t* head = list->head;这可以通过 Node head = list->head;来实现跨度>
  • @karlphillip - 但 list->head 的类型是 Node* 或 Node_t** ,我就是这么定义的。
  • 是的!请改用Node head =list->head;。代码被破坏了。如果你得到了这样的结果并且想让它工作,你就必须修复它。
【解决方案2】:

您正在使用指向指针的指针,您很可能需要指针。

在 List_t 中,您将 head 定义为 Node*,其中 Node 已经是 Node_t* 。

马里奥

【讨论】:

  • 这不是我 4 分钟前在我的答案中发布的吗? =P
  • @Mario The Spoon - 我被要求建立这样的列表。我知道它的奇怪和更好的解决方案是只用一个指针来构建它——但我受限于这个解决方案。为什么这应该是一个问题?
  • @karlphillip: grrrrrrrrrr ;-)
  • @RanZilber:迫使你这样做的要求是什么?只是没有任何意义......
  • @Mario,他们要求你做一个双向链表吗?)
【解决方案3】:

啊,隐藏在 typedef 后面的指针;除非该类型是完全不透明的,否则几乎总是糟糕的juju。为了我的利益,我将删除 typedef,以便更轻松地了解您真正在玩什么。

struct Node_t {   
  void *data ;   
  struct Node_t *next; 
};

struct List_t {   
  struct Node_t **head;   
  struct Node_t **current; 
};

void *ListGetFirst(struct List_t *list)
{
  if( list == NULL || list->head==NULL
  {        
     return NULL;
  }
  list->current=list->head;             
  struct Node_t **head =list->head; // here is the problem
  void *data = (*head)->data;
  return data;           
}           

我得到了 nuthin'。类型似乎都匹配。 -> 运算符最强调没有有任何副作用;它所做的只是取消引用一个指针。 struct List_theadcurrent 的额外间接级别令人头疼,这让我怀疑它们是否被正确分配或分配。我所能想到的是list->head 并没有指向您实际拥有的内存,并且当您到达该点时会以某种方式被覆盖(IOW,您在代码的其他地方调用了未定义的行为)。

简而言之,问题不在于您发布的代码。它可能是您分配和分配列表元素的地方。

【讨论】:

  • 谢谢,这就是我一直在寻找的答案
猜你喜欢
  • 2011-12-03
  • 1970-01-01
  • 2013-03-13
  • 2013-11-14
  • 2011-12-10
  • 2012-02-07
  • 1970-01-01
  • 2023-04-04
  • 2020-07-30
相关资源
最近更新 更多