C 使用指向结构的指针数组时出现分段错误
我必须在数组中保存一些数据的地址。每个数据都是一个类型为“dagNode”的结构。为了完成我的工作,我访问了一个列表,我计算了我想要记录其地址的数据的数量,因此我在内存中分配了正确的空间,最后我重新访问了列表并保存了一些数据的地址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;
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标识的内存问题