在下面的函数中,我正在解析字符串形式的链表并给struct数组赋值。是否有任何方法让我不在循环中使用mallocs。我无法处理glibc错误,所以寻找其他方式。我试图使用char数组而不是char *用于struct字段。但我得到seg错误。实际上这个功能正在运行,但我以后再调用15000次函数,所以我想确保它不会造成任何内存麻烦。
struct CoordNode
{
int resNum;
double coordX;
double coordY;
double coordZ;
char atomName[4];
};
void parseCrdList()
{
int resNum=1;
int tAtomNum,i;
char *tcoordX, *tcoordY, *tcoordZ, *tatomName, tresNum[5];
ccur_node=headCoord_node->next;
struct CoordNode *t;
t=malloc(numofRes*sizeof(struct CoordNode));
i=0;
while (ccur_node!=NULL)
{
tresNum=malloc(5*sizeof(char));
memcpy(tresNum,ccur_node->crdRow+26,4);
resNum=atoi(tresNum);
t[i].resNum=resNum;
tcoordX=malloc(8*sizeof(char));
memcpy(tcoordX,ccur_node->crdRow+35,7);
tcoordY=malloc(8*sizeof(char));
memcpy(tcoordY,ccur_node->crdRow+43,7);
tcoordZ=malloc(8*sizeof(char));
memcpy(tcoordZ,ccur_node->crdRow+51,7);
t[i].coordX=strtod(tcoordX,NULL);
t[i].coordY=strtod(tcoordY,NULL);
t[i].coordZ=strtod(tcoordZ,NULL);
tatomName=malloc(4*sizeof(char));
memcpy(tatomName,ccur_node->crdRow+17,3);
strcpy(t[i].atomName,tatomName);
old_ccur_node=ccur_node;
ccur_node=ccur_node->next;
//free(old_ccur_node);
i++;
}
numofRes=i;
addCoordData(t);
//free(t);
t=NULL;
}
答案 0 :(得分:0)
一些想法和猜测
首先,正如我之前提到的, sizeof(char)在C中总是1 byte
,它实际上是C中的标准字节定义。所以删除那些完全不必要且难以阅读。
回到主要问题。
你永远不会使用大于8的字符数组,所以只需要静态地写8个字节。如果你必须给你打电话15k次,这将节省你很多时间(malloc需要时间为你分配内存)。
根据问题的信息,我猜你的段错误是你没有初始化你用malloc分配的内存或者为auto char [8]
保留的声明的原因
1。您分配(或第二版 - 声明8字节数组)8个字节。它工作正常。但是你在这里得到了8个字节的垃圾。
2. 从列表中复制7个字节。那也没关系。但是你忘记了NULL终止,所以如果你试图将它打印出来,你会得到段错误。编辑如果它有效,那么你可能很幸运,因为它不应该。
<强>解决方案强>
替换char *
女巫char [8]
,删除与{* 1}}相对应的所有malloc
和free
null terminate
char[8]
strcpy
strncpy
}},memcpy
或valgrind
(无论您的选择是什么,取决于您对列表中的数据的信心程度是否正确)都会向他们提供数据。
在进一步使用之前,请使用{{1}}检查您的代码。
答案 1 :(得分:0)
令人惊讶的是你说这个功能对你有用。从我从你的代码中看到的我开始有很多内存泄漏,因为没有那些8字节的mallocs被炒过。
第二件事是,在知道要解析的实际数据记录数之前,您似乎正在分配CoordNode
数组。我在分配之前添加了适当的numofRes
计算。
由于您不修改输入数据,实际上并不需要所有malloc和memcpy,因此您可以立即使用crdRow
中的strtod()
,假设它具有char *
类型。< / p>
最后一件事:在一个地方进行分配并在另一个地方释放数据通常是一种不好的做法。因此,在解析它之后,最好在分配它的地方释放headCoord_node
结构。释放t
的决定取决于addCoordData(t)
如何处理其参数。
void parseCrdList()
{
struct CoordNode *t;
int i;
// count number of records to parse
numofRes = 0;
ccur_node = headCoord_node->next;
while (ccur_node != NULL)
{
numofRes++;
ccur_node=ccur_node->next;
}
t=malloc(numofRes*sizeof(struct CoordNode));
i=0;
ccur_node = headCoord_node->next;
while (ccur_node!=NULL)
{
t[i].resNum=atoi(ccur_node->crdRow+26);
t[i].coordX=strtod(ccur_node->crdRow+35,NULL);
t[i].coordY=strtod(ccur_node->crdRow+43,NULL);
t[i].coordZ=strtod(ccur_node->crdRow+51,NULL);
strncpy(t[i].atomName,ccur_node->crdRow+17,4);
ccur_node=ccur_node->next;
i++;
}
numofRes=i;
addCoordData(t);
//free(t); // <<< it depends on how addCoordData treats t
}