C 使用指向结构的指针数组时出现分段错误

C 使用指向结构的指针数组时出现分段错误,c,pointers,struct,dynamic-memory-allocation,C,Pointers,Struct,Dynamic Memory Allocation,我必须在数组中保存一些数据的地址。每个数据都是一个类型为“dagNode”的结构。为了完成我的工作,我访问了一个列表,我计算了我想要记录其地址的数据的数量,因此我在内存中分配了正确的空间,最后我重新访问了列表并保存了一些数据的地址 struct dagNode *buildBST(struct dagNode *rootList){ struct dagNode *head, **xTest; head = rootList; int numXtest=0;

我必须在数组中保存一些数据的地址。每个数据都是一个类型为“dagNode”的结构。为了完成我的工作,我访问了一个列表,我计算了我想要记录其地址的数据的数量,因此我在内存中分配了正确的空间,最后我重新访问了列表并保存了一些数据的地址

    struct dagNode *buildBST(struct dagNode *rootList){
    struct dagNode *head, **xTest;
    head = rootList;
    int numXtest=0;

    rootList = nextNode(TYPE_XTEST, rootList);

    while ( !IS_TERMINATED( rootList ) ){   // first visit
        numXtest++;
        rootList = nextNode(TYPE_XTEST, rootList); }

    xTest = (struct dagNode **) malloc( sizeof(struct dagNode ) * numXtest);
    int i=0; rootList = nextNode(TYPE_XTEST, head);

    for(i=0; i<numXtest; i++){      // second visit, saving the address of some datas
        rootList = nextNode(TYPE_XTEST, rootList);
        xTest[i] = rootList; i++;
    >>> printf("t=%d,val=%d\t", xTest[i]->nodeType, xTest[i]->val); } // segmentation fault

    return head;
    }
nextNode()
似乎是罪魁祸首

编辑: 请注意,您还将在每次迭代中递增
i
两次。这肯定会崩溃。

nextNode()
似乎是罪魁祸首

编辑:
请注意,您还将在每次迭代中递增
i
两次。这肯定会崩溃。

xTest
指针的类型和您在
malloc
中分配的大小之间存在不匹配。如果
xTest
的类型为
struct dagNode**
,则正确的分配应为:

xTest = malloc(sizeof(struct dagNode *) * numXtest);

您可能希望将
numXtest
指针分配给结构,而不是
numXtest
结构。

指针的类型与在
malloc
中分配的大小不匹配。如果
xTest
的类型为
struct dagNode**
,则正确的分配应为:

xTest = malloc(sizeof(struct dagNode *) * numXtest);

可能你想分配
numXtest
指向结构的指针,而不是
numXtest
结构。

对不起,这篇文章没有回答这个问题。我只想给你一个替代编码风格的例子。从中挑选你喜欢的

我没有改变代码的含义,除了删除了其他答案/评论中已经指出的最明显的错误

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
  ...
} dagNode;

dagNode* buildBST (dagNode* rootList)
{
  dagNode*  head;
  dagNode** xTest;
  int numXtest=0;
  int i=0;

  head = rootList;
  rootList = nextNode(TYPE_XTEST, rootList);

  while (!IS_TERMINATED(rootList))               // first visit
  {
    numXtest++;
    rootList = nextNode(TYPE_XTEST, rootList);
  }

  xTest = malloc(sizeof(dagNode) * numXtest);
  rootList = nextNode(TYPE_XTEST, head);

  for(i=0; i<numXtest; i++)                      // second visit, saving the address of some datas
  {      
    rootList = nextNode(TYPE_XTEST, rootList);
    xTest[i] = rootList;

    printf("t=%d,val=%d\t", 
           xTest[i]->nodeType,
           xTest[i]->val);
  }

  return head;
}


dagNode *nextNode (int typeOfNextNode, dagNode *node)
{
  if (IS_TERMINATED(node))
  {
    return node;
  }

  node = node->next;

  if (typeOfNextNode == TYPE_EDGE_OR_GAP)
  {
    while ( !IS_TERMINATED(node) &&
            !IS_AN_EDGE(node) &&
            !IS_A_GAP(node) )
    {
      node = node->next;
    }
  }
  else
  {
    while ( !IS_TERMINATED(node) &&
            (node->nodeType != typeOfNextNode) )
    {
      node = node->next;
    }
  }

  return node;
}
#包括
#包括
类型定义结构
{
...
}dagNode;
dagNode*buildBST(dagNode*rootList)
{
节点*头;
dagNode**xTest;
int numXtest=0;
int i=0;
head=根列表;
rootList=nextNode(TYPE_XTEST,rootList);
而(!IS_TERMINATED(rootList))//第一次访问
{
numXtest++;
rootList=nextNode(TYPE_XTEST,rootList);
}
xTest=malloc(sizeof(dagNode)*numXtest);
rootList=nextNode(TYPE_XTEST,head);
对于(i=0;inodeType,
xTest[i]>val);
}
回流头;
}
dagNode*nextNode(int-typeOfNextNode,dagNode*node)
{
如果(是_终止的(节点))
{
返回节点;
}
节点=节点->下一步;
if(typeOfNextNode==TYPE_EDGE_或_GAP)
{
当(!被_终止时(节点)&&
!是否为边(节点)&&
!是否为间隙(节点))
{
节点=节点->下一步;
}
}
其他的
{
当(!被_终止时(节点)&&
(节点->节点类型!=typeOfNextNode))
{
节点=节点->下一步;
}
}
返回节点;
}

很抱歉,这篇文章没有回答这个问题。我只想给你一个替代编码风格的例子。从中挑选你喜欢的

我没有改变代码的含义,除了删除了其他答案/评论中已经指出的最明显的错误

#include <stdio.h>
#include <stdlib.h>

typedef struct
{
  ...
} dagNode;

dagNode* buildBST (dagNode* rootList)
{
  dagNode*  head;
  dagNode** xTest;
  int numXtest=0;
  int i=0;

  head = rootList;
  rootList = nextNode(TYPE_XTEST, rootList);

  while (!IS_TERMINATED(rootList))               // first visit
  {
    numXtest++;
    rootList = nextNode(TYPE_XTEST, rootList);
  }

  xTest = malloc(sizeof(dagNode) * numXtest);
  rootList = nextNode(TYPE_XTEST, head);

  for(i=0; i<numXtest; i++)                      // second visit, saving the address of some datas
  {      
    rootList = nextNode(TYPE_XTEST, rootList);
    xTest[i] = rootList;

    printf("t=%d,val=%d\t", 
           xTest[i]->nodeType,
           xTest[i]->val);
  }

  return head;
}


dagNode *nextNode (int typeOfNextNode, dagNode *node)
{
  if (IS_TERMINATED(node))
  {
    return node;
  }

  node = node->next;

  if (typeOfNextNode == TYPE_EDGE_OR_GAP)
  {
    while ( !IS_TERMINATED(node) &&
            !IS_AN_EDGE(node) &&
            !IS_A_GAP(node) )
    {
      node = node->next;
    }
  }
  else
  {
    while ( !IS_TERMINATED(node) &&
            (node->nodeType != typeOfNextNode) )
    {
      node = node->next;
    }
  }

  return node;
}
#包括
#包括
类型定义结构
{
...
}dagNode;
dagNode*buildBST(dagNode*rootList)
{
节点*头;
dagNode**xTest;
int numXtest=0;
int i=0;
head=根列表;
rootList=nextNode(TYPE_XTEST,rootList);
而(!IS_TERMINATED(rootList))//第一次访问
{
numXtest++;
rootList=nextNode(TYPE_XTEST,rootList);
}
xTest=malloc(sizeof(dagNode)*numXtest);
rootList=nextNode(TYPE_XTEST,head);
对于(i=0;inodeType,
xTest[i]>val);
}
回流头;
}
dagNode*nextNode(int-typeOfNextNode,dagNode*node)
{
如果(是_终止的(节点))
{
返回节点;
}
节点=节点->下一步;
if(typeOfNextNode==TYPE_EDGE_或_GAP)
{
当(!被_终止时(节点)&&
!是否为边(节点)&&
!是否为间隙(节点))
{
节点=节点->下一步;
}
}
其他的
{
当(!被_终止时(节点)&&
(节点->节点类型!=typeOfNextNode))
{
节点=节点->下一步;
}
}
返回节点;
}

向我们展示
nextNode
函数。您可以通过在调试器中运行代码来隔离问题。这是我很久以来看到的最难理解的代码布局。为了每个人的理智,请采用更正统的形式。至少,
if
else
应该垂直对齐,
}
应该在行的开头,结尾不隐藏。永远不要在C.Read中键入malloc的结果。向我们展示
nextNode
函数。您可以通过在调试器中运行代码来隔离问题。这是我很久以来看到的最难理解的代码布局。为了每个人的理智,请采用更正统的形式。至少,
if
else
应该垂直对齐,
}
应该在行首,而不是在行尾隐藏。切勿在C.Read中键入malloc的结果。这是故障的最可能原因。在循环中,有一个隐藏的增量
xTest[i]=rootList;i++就在打印之前。因此,在打印数据之前,跳过刚刚设置的指针。由于
循环控制的
也会增加
i
,因此您(OP)应该删除
i++在循环内部。@Blagovest发现的内存问题也需要处理,但是如果
sizeof(struct dagNode)>=sizeof(struct dagNode*)
(这是不可避免的,因为节点包含指针),该缺陷只会浪费内存,而不会导致崩溃。这是故障的最可能原因。在循环中,有一个隐藏的增量
xTest[i]=rootList;i++就在打印之前。因此,在打印数据之前,跳过刚刚设置的指针。由于
循环控制的
也会增加
i
,因此您(OP)应该删除
i++在循环内部。由@Bl标识的内存问题