gpt4 book ai didi

c - 调用 next() 时最后一个元素不断重复。不返回 NULL

转载 作者:行者123 更新时间:2023-11-30 19:30:52 25 4
gpt4 key购买 nike

嘿,我正在尝试实现一个可以存储任何类型元素的通用列表迭代器。它还有其他文件来处理正整数类型和字符串类型。该文件编译正确。但是,当我在测试用例代码中调用 next() 函数(特别是下面代码中的测试用例 2)时,它会打印出添加的所有元素,但当它到达列表中的最后一个元素时,它会不断重复最后一个元素,当没有最后一个元素时,它应该返回 NULL

这是下一个函数:

void *next(IteratorG it){

Node *tempo;
if ((tempo = malloc(sizeof(Node))) == NULL) {
return 0;
}

if(it->curr->next==NULL)
{
return NULL;
}
tempo=it->curr;
it->curr=it->curr->next;

// move to next node in list
return tempo->value;
}

我使用的是 Linux 环境,错误从结果中可以看出。整个程序的代码如下:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include "iteratorG.h"

typedef struct Node {

void *value; // value of thee list item
struct Node *prev;
// pointer previous node in list
struct Node *next;
// pointer to next node in list

// implemented struct here ..
} Node;

typedef struct IteratorGRep {

int numofit; // count of items in list
Node *head; // first node in list
Node *curr; // current node in list
Node *tail; // last node in list

ElmCompareFp cmpElm;
ElmNewFp newElm;
ElmFreeFp freeElm;

// implemented struct here ..

} IteratorGRep;


/*


//Your functions below ....
*/


IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp){

IteratorG newit;


if ((newit = malloc(sizeof (struct IteratorGRep)))==NULL)
{
printf("Error...! \n");

}

//assert (newit != NULL);
newit->numofit = 0;
newit->head = NULL;
newit->tail = NULL;
newit->curr = NULL;
newit->cmpElm=cmpFp;
newit->newElm=newFp;
newit->freeElm=freeFp;
return newit;

// implemented function here and changed return value
}



int add(IteratorG it, void *vp){

Node *temp;
if ((temp = malloc(sizeof(Node))) == NULL) {
return 0;
}

temp->value = it->newElm(vp);
temp->next=NULL;

if(it->curr==NULL)
{
//temp->next=it->curr;
it->curr=temp;
it->tail=it->head=it->curr;
}

temp->next=it->curr;
it->curr->prev=temp;
it->curr=temp;
it->head=it->curr;
//it->curr->prev=temp;
/*temp->next = it->curr;
it->curr = temp;
*/
// add node to list from front
return 1;
}
int hasNext(IteratorG it){

if(it->curr->next==NULL)
{
return 0;
}


// check if theres next element/node
return 1;
}
int hasPrevious(IteratorG it){

if(it->curr->prev!=NULL)
{
return 1;
}
// check if theres previous element/node
return 0;
}
void *next(IteratorG it){

Node *tempo;
if ((tempo = malloc(sizeof(Node))) == NULL) {
return 0;
}

if(it->curr->next==NULL)
{
return NULL;
}
tempo=it->curr;
it->curr=it->curr->next;

// implemented function here
return tempo->value;
}
void *previous(IteratorG it){

Node *tempor;
if ((tempor = malloc(sizeof(Node))) == NULL) {
return 0;
}
tempor=it->curr;
if(tempor->prev==NULL)
{
return NULL;
}
tempor=it->curr->prev;

it->curr=it->curr->prev;
//tempor=it->curr;

// move to next node in list
return tempor->value;
}
int del(IteratorG it){
if(it->curr->prev!=NULL)
{
Node *temp_curr=it->curr;
Node *temp_prev=it->curr->prev->prev;
temp_curr->prev=temp_prev;
temp_prev->next=temp_curr;
return 1;

}// delete previous node from list
else
return 0;
}
int set(IteratorG it, void *vp){
if(it->curr->prev!=NULL)
{

it->curr->prev->value=vp;


/*

Node *wep;
if ((wep = malloc(sizeof(Node))) == NULL) {
return 0;
}


wep->value=it->newElm(vp);


store_next=it->curr;
store_prev=it->curr->prev->prev;
store_next->prev=wep;
wep->next=store_next;

store_prev->next=wep;
wep->prev=store_prev;
*/


return 1;
}
// change previous node value with new
return 0;
}
IteratorG advance(IteratorG it, int n){



//To be implemented
//move forward by n times
return NULL;
}
void reverse(IteratorG it){
Node *curr = it->head;
Node *temp = NULL;
while(curr != NULL) {
temp = curr->next;
curr->next = curr->prev;
curr->prev = temp;
curr = temp;
}
temp = it->head;
it->head = it->tail;
it->tail = temp;// reverse elements of whole list
}
IteratorG find(IteratorG it, int (*fp) (void *vp) ){
// To be implemented
// Find elements of vp in list after current position and put in new list.return the list.
return NULL;
}
int distanceFromStart(IteratorG it){

Node *c=it->curr;
int count=0;


while(c->prev!=NULL)
{
c=c->prev;
count++;
}
return count;
// count number of elements from start of list to current position

}
int distanceToEnd(IteratorG it){

Node *cu=it->curr;
int count=0;

while(cu->next!=NULL)
{
cu=cu->next;
count++;
}
return count;
// count number of elements from end of list to current position
}
void reset(IteratorG it){



while(it->curr->prev!=NULL)
{

it->curr=it->curr->prev;

}
return;
// move current position to start of list

}
void freeIt(IteratorG it){
assert(it != NULL);
Node *curr, *prev;
curr = it->head;
while (curr != NULL) {
prev = curr;
curr = curr->next;
free(prev->value);
free(prev);
}
free(it); // free items

}

这是代码的头文件:

#ifndef LISTITERATORG_H
#define LISTITERATORG_H

#include <stdio.h>

typedef struct IteratorGRep *IteratorG;

typedef int (*ElmCompareFp)(void const *e1, void const *e2);
typedef void *(*ElmNewFp)(void const *e1);
typedef void (*ElmFreeFp)(void *e1);


IteratorG newIterator(ElmCompareFp cmpFp, ElmNewFp newFp, ElmFreeFp freeFp);
int add(IteratorG it, void *vp);
int hasNext(IteratorG it);
int hasPrevious(IteratorG it);
void *next(IteratorG it);
void *previous(IteratorG it);
int del(IteratorG it);
int set(IteratorG it, void *vp);
IteratorG advance(IteratorG it, int n);
void reverse(IteratorG it);
IteratorG find(IteratorG it, int (*fp) (void *vp) );
int distanceFromStart(IteratorG it);
int distanceToEnd(IteratorG it);
void reset(IteratorG it);
void freeIt(IteratorG it);

#endif

其中一个功能尚未实现,并在代码本身中指出。但我想这可能不是问题的根源。我认为 NULL 在这里没有被正确使用。

编辑:这是测试用例代码。仅在上面的程序中测试用例代码没有错误:

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <string.h>
#include "iteratorG.h"
#include "positiveIntType.h"
#include "stringType.h"

#define MAXARRAY 5

/* Helper Functions Below */

/* Returns 1 if marks >= 50, 0 otherwise */
int passMarks(void *marks){
return (*((int *) marks) >= 50);

/* Easy to understand below ..
int *ip = (int *) marks;
if(*ip >= 50) { return 1; }
else { return 0; }
*/
}

/* Returns 1 if str starts with "jo" */
int prefixJo(void *str){
return (strncmp("jo", (char *) str, 2) == 0) ;
}

/* A function to print a string from a void pointer */
void prnStr(void *vp){
assert(vp != NULL);
printf(" %s", (char *) vp );
}

/* A function to print an integer from a void pointer */
void prnInt(void *vp){
assert(vp != NULL);
printf(" %d", *((int *) vp) );
}

/* Prints previous element using the given function 'fp'
examples: prnPrev(it1, prnInt); prnPrev(it2, prnStr);
*/
void prnPrev(IteratorG it, void (*fp) (void *p) ){
void *prevP = previous(it);
assert(prevP != NULL);
printf("> Previous value is: ");
fp(prevP);
printf("\n");
}

/* Prints next element using the given function 'fp'
examples: prnNext(it1, prnInt); prnNext(it2, prnStr);
*/
void prnNext(IteratorG it, void (*fp) (void *p) ){
void *nextP = next(it);
assert(nextP != NULL);
printf("> Next value is: ");
fp(nextP);
printf("\n");
}

/* Prints elements of 'it' from current to last position
using the given function 'fp'. The current position
of 'it' will change to the end of the list.
examples: prnIt(it1, prnInt); prnIt(it2, prnStr);
*/
void prnIt(IteratorG it, void (*fp) (void *p) ){
int count = 0;
while(hasNext(it)){
void *nextP = next(it);
count++;
if(count > 1) { printf(", "); }
fp(nextP);
}
printf("\n");
}


/* Few Tests Below */

void test1(){
printf("\n--==== Test-01 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 25, 78, 6, 82 , 11};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}
freeIt(it1);
printf("--==== End of Test-01 ====------\n");
}

void test2(){
printf("\n--==== Test-02 ====------\n");
IteratorG it1 = newIterator(positiveIntCompare, positiveIntNew, positiveIntFree);
int a[MAXARRAY] = { 72, 14, 62, 8, 93};
for(int i=0; i<MAXARRAY; i++){
int result = add(it1 , &a[i]);
printf("> Inserting %d: %s \n", a[i], (result==1 ? "Success" : "Failed") );
}

prnNext(it1, prnInt);
prnNext(it1, prnInt);
prnPrev(it1, prnInt);

int newVal1 = 55;
int result1 = set(it1, &newVal1);
printf("> Set value: %d ; return val: %d \n", newVal1, result1 );

prnPrev(it1, prnInt);

freeIt(it1);
printf("--==== End of Test-02 ====------\n");
}



int main(int argc, char *argv[])
{


test1();
test2();

return EXIT_SUCCESS;

}

最佳答案

add函数中,当您第一次添加时,it->currnull并且它使temp ->next 指向自身,不为 null,因此链表似乎没有尽头:

您的原始代码:

 if(it->curr==NULL)
{
it->curr=temp; // the current element is the add element
it->tail=it->head=it->curr;
}

temp->next=it->curr; // for the first element, it->curr is already valued to temp : temp->next points to temp :(

add 函数可以是:

// add node to list from front 
int add(IteratorG it, void *vp){

Node *temp;
if ((temp = malloc(sizeof(Node))) == NULL) {
return 0;
}

temp->value = it->newElm(vp);

temp->prev = null;
temp->next = it->curr;
if (it->curr != NULL)
it->curr->prev = temp;
it->curr = temp;
it->head = it->curr;
return 1;
}

而且,我知道这不是您所要求的,但是 nextprevious 中存在丑陋内存泄漏功能...

关于c - 调用 next() 时最后一个元素不断重复。不返回 NULL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49912688/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com