这是我的结构:
typedef struct gene{
char* name;
int length;
int* sequence;
} gene;
typedef struct genes{
gene gene;
struct genes* next;
} genes;
构造 函数:
genes* createGenes(gene newGene){
genes* geneArr = malloc(sizeof(genes));
if (NULL != geneArr){
geneArr->gene = newGene;
geneArr->next = NULL;
}
return geneArr;
}
void deleteGenes(genes* geneArr){
if(NULL != geneArr->next){
deleteGenes(geneArr->next);
}
free(geneArr);
}
genes* addGene(genes* geneList, gene newGene){
genes* toAdd = createGenes(newGene);
if (NULL != toAdd){
geneList->next = toAdd;
}
return geneList;
}
和一个函数(它创建一个具有给定长度的序列。对于 5 ->{2, 2, 2, 2, 2}
):
gene twosGene(char* name, int length){
gene newGene;
newGene.name = name;
newGene.length = length;
newGene.sequence = (int*)malloc(sizeof(int) * length);
for(int i = 0; i < length; i++){
newGene.sequence[i] = 2;
}
return newGene;
}
这是我的main()
函数:
int main(){
int count = 1;
genes* geneArr = createGenes(twosGene("gene1", count++));
for (int i = 0; i < 4; ++i) {
geneArr = addGene(geneArr, twosGene("geneLoop", count++));
}
genes* iter;
for (iter = geneArr; NULL != iter; iter = iter->next) {
printf("gene=%dn", iter->gene.length);
free(iter->gene.sequence);
}
deleteGenes(geneArr);
return 0;
}
我希望这个输出:
gene=1
gene=2
gene=3
gene=4
gene=5
但相反,我得到了这个:
gene=1
gene=5
此外,当我使用Valgrind时,我的程序中也有一些泄漏。
==20580== HEAP SUMMARY:
==20580== in use at exit: 132 bytes in 6 blocks
==20580== total heap usage: 11 allocs, 5 frees, 1,244 bytes allocated
我想不通为什么。感谢您的帮助。
在此函数中
genes* addGene(genes* geneList, gene newGene){
genes* toAdd = createGenes(newGene);
if (NULL != toAdd){
geneList->next = toAdd;
}
return geneList;
}
您始终覆盖最初在语句中创建的节点旁边的数据成员
genes* geneArr = createGenes(twosGene("gene1", count++));
您似乎想在当前列表的末尾添加一个新节点。在这种情况下,函数将如下所示
genes* addGene(genes* geneList, gene newGene){
genes* toAdd = createGenes(newGene);
if (NULL != toAdd){
genes *current = geneList;
while ( current->next != NULL ) current = current->next;
current->next = toAdd;
}
return geneList;
}
但是,通常即使此函数定义也是无效的,因为最初geneList
可以等于 NULL。因此,使用您的方法应按以下方式重写函数
genes* addGene(genes* geneList, gene newGene){
genes* toAdd = createGenes(newGene);
if (NULL != toAdd){
if ( geneList == NULL )
{
geneList = toAdd;
}
else
{
genes *current = geneList;
while ( current->next != NULL ) current = current->next;
current->next = toAdd;
}
}
return geneList;
}
但是,如果将指针传递到列表的头部指针,也可以改进此函数实现。
例如
int addGene( genes **geneList, gene newGene )
{
genes* toAdd = createGenes(newGene);
int success = toAdd != NULL;
if ( success )
{
while ( *geneList != NULL ) geneList = &( *geneList )->next;
*geneList = toAdd;
}
return success;
}
在这种情况下,可以像这样调用函数
genes* geneArr = createGenes(twosGene("gene1", count++));
for (int i = 0; i < 4; ++i) {
addGene( &geneArr, twosGene("geneLoop", count++));
}
在:
genes* geneArr = createGenes(twosGene("gene1", count++));
for (int i = 0; i < 4; ++i) {
geneArr = addGene(geneArr, twosGene("geneLoop", count++));
}
第一个分配列表的负责人。在 for 循环中,接下来每次迭代都会覆盖此头部。你应该/可以做:
genes* geneArr = createGenes(twosGene("gene1", count++));
genes *geneNext= geneArr;
for (int i = 0; i < 4; ++i) {
geneNext = addGene(geneNext, twosGene("geneLoop", count++));
}
此外,addGene
必须前进指针才能使上述操作正常工作。
genes* addGene(genes* geneList, gene newGene){
genes* toAdd = createGenes(newGene);
if (NULL != toAdd){
geneList->next = toAdd;
genelist= geneList->next; // add this statement.
}
return geneList;
}
现在你可以打印它,因为你还有头。
addGene
函数不会添加到列表的末尾。它只是将新基因与第一个基因联系起来。正如Valgrind报道的那样,列表中第一个基因之后的任何东西都被"遗忘",导致记忆泄漏。
以下是应该可以工作的addGenes
函数的更新版本:
genes* addGene(genes* geneList, gene newGene){
genes* toAdd = createGenes(newGene);
if (NULL != toAdd){
if (geneList == NULL){
geneList = toAdd;
} else {
genes *last = geneList;
while (last->next != NULL){
last = last->next;
}
last->next = toAdd;
}
}
return geneList;
}