Malloc与自由错误
在下面的函数中,我将解析一个链表中的字符串,并将值赋给struct数组。是否有任何方法可以让我在while循环中不使用mallocs。我无法处理glibc错误,因此正在寻找其他方法。我尝试对结构字段使用char数组而不是char*。但我得到了seg错误。实际上,这个函数正在工作,但是我必须在15000次之后调用这个函数,所以我想确保它不会造成任何内存问题Malloc与自由错误,c,string,memory-management,struct,malloc,C,String,Memory Management,Struct,Malloc,在下面的函数中,我将解析一个链表中的字符串,并将值赋给struct数组。是否有任何方法可以让我在while循环中不使用mallocs。我无法处理glibc错误,因此正在寻找其他方法。我尝试对结构字段使用char数组而不是char*。但我得到了seg错误。实际上,这个函数正在工作,但是我必须在15000次之后调用这个函数,所以我想确保它不会造成任何内存问题 struct CoordNode { int resNum; double coordX; double coordY; double coo
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;
}
一些想法和猜测。
首先,正如我前面提到的,sizeof(char)在C中总是
1字节,实际上它是C中的标准字节定义。因此,请删除那些完全不必要且难以读取的字节。
回到主要问题。
您从不使用大于8的字符数组,所以只需将其静态地设置为8字节长。如果您必须调用函数15k次,这将节省大量时间(malloc需要时间为您分配内存)。
根据问题中的信息,我猜您的SEGFULT是您没有初始化分配给malloc或保留给autochar[8]
的内存及其声明的原因
1。您分配(或第二版本-声明8字节数组)8个字节。它很好用。但是这里有8个字节的垃圾
2。从列表中复制7个字节。那也很好。但是您忘记了NULL终止,所以如果您尝试将其打印回来,您会得到SEGFULT。编辑如果它工作,那么您可能会幸运,因为它不应该
解决方案
替换char*
开关char[8]
,删除所有malloc
s和free
s对应于这些char*,null终止所有char[8]
后的strcpy
,或memcpy
(无论您的选择是什么,这取决于您对列表中数据正确性的信心程度)向他们提供数据
在进一步使用之前,请使用valgrind
检查您的代码。您说此函数对您有效,这让人惊讶。从您的代码中我看到,我一开始就有很多内存泄漏,因为这些8字节malloc中没有一个被炸过
第二件事是,在知道要解析的实际数据记录数之前,您似乎正在分配coordode
数组。我在分配之前添加了适当的numofRes
计算
由于不修改输入数据,实际上不需要所有这些malloc和memcpy,因此可以立即在strod()中使用crdRow
,假设它有char*
类型
最后一件事:通常在一个位置进行分配并在另一个位置释放数据是一种不好的做法。因此,最好在解析后将headCoord_节点
结构释放到分配位置。释放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
}
void parseCrdList()
{
结构坐标*t;
int i;
//计数要分析的记录数
numofRes=0;
ccur\u节点=总部节点->下一步;
while(ccur_节点!=NULL)
{
numofRes++;
ccur\u节点=ccur\u节点->下一步;
}
t=malloc(numofRes*sizeof(struct coordode));
i=0;
ccur\u节点=总部节点->下一步;
while(ccur_节点!=NULL)
{
t[i].resNum=atoi(ccur_节点->crdRow+26);
t[i].coordX=strtod(ccur_节点->crdRow+35,空);
t[i].coordY=strtod(ccur_节点->crdRow+43,空);
t[i].coordZ=strtod(ccur_node->crdRow+51,空);
strncpy(t[i].原子名,ccur_节点->crdRow+17,4);
ccur\u节点=ccur\u节点->下一步;
i++;
}
numofRes=i;
addCoordData(t);
//free(t);//听起来您真正的问题是如何使用字符数组,而不是为tcoordX、tcoordY、tccordZ等使用malloc-ed内存。显示该版本的代码并找出出现seg错误的原因可能会更有效率。根据定义,sizeof(char)=C中的1字节。