简体   繁体   English

如何使用指针访问递归结构

[英]How to access recursive structure with pointers

I am getting a really strange error in my C program and therefore I need your help guys! 我的C程序遇到一个非常奇怪的错误,因此我需要您的帮助! So I have a recursive structure called path, where sometimes I store the address of the "parent" path in the structure field mother: 因此,我有一个称为path的递归结构,有时在其中将“父”路径的地址存储在结构字段mother中:

 typedef struct path{

  struct path* mother;
  struct path** children;
  int length;
  uint8_t* inf;
 } path;

So in my example I just generate one path like this: 因此,在我的示例中,我只生成了一条这样的路径:

  int child_num=2;
  int bytes=10;
  path* my_path=malloc(sizeof(path));
  if (path==NULL) throw error...

  my_path->inf=malloc(sizeof(uint8_t)*bytes);
  memset(my_path->inf, 4, bytes);

  my_path->children=malloc(sizeof(path*)*child_num);

  for(int i=0; i<child_num; i++){
      my_path->children[i]->mother=my_path;
      my_path->children[i]->inf=malloc(sizeof(uint8_t)*bytes);
      memset(my_path->children[i]->inf, 5, bytes);
  }

So now since I stored the link to the parent structure, I want to use another helping pointer to get access to its information: 因此,既然我将链接存储到父结构,那么我想使用另一个帮助指针来访问其信息:

  path* my_pointer=my_path->children[0]->mother;  //this is just for the example

So i checked the addresses and everything seems to be alright, but if I know use the pointer in another method, pointing to the field "inf", it works if I use the variable "path" so: 因此,我检查了地址,一切似乎都很好,但是如果我知道在另一种方法中使用指针,则指向字段“ inf”,如果我使用变量“ path”,则可以正常工作,因此:

     method(path->inf, bytes);

it is fine, but as soon as I do: 很好,但是只要我这样做:

    method(my_pointer->inf, bytes);

the method crashes at the marked line: 该方法在标记的行崩溃:

 void method(uint8_t* element, int bytes) {

     if (element==NULL) ... //<=== here it crashes
     //do something

} }

I really dont get what I am doing wrong, I printed the addresses and everything seems to be good, even if I access a certain byte over the variable "my_pointer", so like 我真的不明白我在做什么错,我打印了地址,而且一切似乎都很好,即使我通过变量“ my_pointer”访问了某个字节,例如

      my_pointer->inf[1]

it returns me the corresponding value, but in the separate method it doesnt work. 它返回我相应的值,但是在单独的方法中它不起作用。

Like the comments indicate we can't exactly answer your question with the information provided, but we can point you in the right direction. 就像评论中指出的那样,我们无法使用所提供的信息确切地回答您的问题,但是我们可以为您指明正确的方向。

First, I noticed in your examples that you're using path as a variable name to a typedef'd path structure. 首先,我在您的示例中注意到您正在使用path作为类型定义的path结构的变量名。 You need to either be more verbose with your variable names or actually copy paste some code to make sure that we can look at the actual problem, because it could simply be an issue with naming. 您可能需要更详细地使用变量名,或者实际复制粘贴一些代码以确保我们可以查看实际问题,因为这可能只是命名问题。

All in all I think it would do you a world of good to employ a bit of code hygiene. 总而言之,我认为采用一点代码卫生将为您带来很多好处。 Organize some of the functions you use for data structure overhead at file scope: 在文件范围内整理一些用于数据结构开销的功能:

static int path_alloc(path* p);
static int path_alloc_kids(path* p, int num);

static int path_alloc(path* p) {
  if(p == NULL) { return -1; }

  p = (path*)malloc(sizeof(path));
  if(p == NULL) { return -2; }

  return 0;
}

static int path_alloc_kids(path* p, int num) {
  if(p == NULL || num <= 0) { return -1; }

  if(!path_alloc(p)) { /* Easier to read and understand, no error handling here to muddle things up */

    /* You don't actually need a path**, do you? Think of char *argv[] a.k.a. char **argv, is that what you're actually going for? */
    p->children = (path*)malloc(sizeof(path) * num);
    if(p->children == NULL) { return -2; }
    p->length = num;
  } else { return -1; } /* Simple */

  return 0;
}

This makes it a LOT easier to understand your code, which is the main issue with pointers. 这使很多人更容易理解您的代码,这是指针的主要问题。 Add in some methods to free the allocated children and roots and you're set to use this path structure in a relatively abstracted way. 添加一些方法以释放分配的子代和根,您将以相对抽象的方式使用此路径结构。 You may want to consider using a path and a path_node in a linked-list fashion, that way you only allocate what you need. 您可能要考虑以链接列表的方式使用pathpath_node ,那样您就只分配需要的内容。

struct spath_node; /* So it knows of itself */
typedef struct spath_node {
  struct spath_node *parent;
  struct spath_node *next;
  uint8_t *data;
  int data_size;
} path_node;

Then allocate by passing in a data size and parent, a NULL parent could mean it's a root node. 然后通过传入数据大小和父节点进行分配, NULL父节点可能意味着它是根节点。

static int path_alloc_node(path_node *parent, int data_size, uint8_t *data);

This makes for relatively slow insert/traversal, but easier to understand where you went wrong. 这使得插入/遍历相对较慢,但更容易理解出错的地方。

EDIT : To be clear, this is how we would add children to the linked-list example: 编辑 :要清楚,这是我们将子级添加到链接列表示例的方式:

static int path_alloc_node(path_node *parent, int data_size, uint8_t *data) {
  path_node *tmp;

  if(parent == NULL || data_size <= 0) { return -1; }
  if(parent->next != NULL) { return -3; }

  tmp = (path_node*)malloc(sizeof(path_node));
  if(tmp == NULL) { return -2; }
  else parent->next = tmp;

  if(data == NULL) { /* Assume the caller is requesting a new data block of the given size */
    data = (uint8_t*)malloc((size_t)data_size);
    if(data == NULL) { return -2; }
  }

  parent->next->data = data;
  parent->next->data_size = data_size;
  parent->next->next = NULL;
  parent->next->parent = parent;

  return 0;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM