我正在處理雙向鏈表,並且遇到了一個我沒有解決的問題。爲了更好地說明這一點,下面是代碼,然後再說明問題所在。在雙向鏈表中的Const結構正在修改中C
Dblist.h
# Ifndef CGI_DBLIST_H
# Define CGI_DBLIST_H
# Include "malloc.h"
/* Structure represantative an element of the list. */
typedef struct elem
{
int value;
struct elem * prev;
struct elem * next;
} Elem;
/* Structure access to the list. */
typedef struct
{
elem * first;
elem * last;
} dblist;
# ifdef __cplusplus
extern "C" {
# Endif
void Init (dblist * l); /* Initialize the list */
void pushback (dblist * s, int val); /* Add a value at end */
void PushFront (dblist * l, int val); /* Add a value at start */
int PopBack (dblist * l); /* Remove value at end */
int PopFront (dblist * l); /* Remove value at start */
void View (dblist l); /* Display whole list */
void ViewReverse (dblist l); /* Display all reversed */
void Clear (dblist * l); /* discard list */
dblist getInterval (dblist const * s);
#ifdef __cplusplus
}
#endif
#endif /* CGI_DBLIST_H */
Dblist.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "dblist.h"
#include "malloc.h"
void Init (dblist * l)
{
l-> first = NULL;
l-> last = NULL;
}
void pushback (dblist * s, int val)
{
elem * n = malloc (sizeof (elem));
if (! n) exit (EXIT_FAILURE);
n-> value = val;
n-> prev = l-> last;
n-> next = NULL;
if (s-> last) s-> last-> next = n;
else s-> first = n;
l-> last = n;
}
void PushFront(dblist *l, int val)
{
elem *n = malloc(sizeof(elem));
if(!n) exit(EXIT_FAILURE);
n->value = val;
n->next = l->first;
n->prev = NULL;
if(l->first) l->first->prev = n;
else l->last = n;
l->first = n;
}
int PopBack(dblist *l)
{
int val;
elem *tmp = l->last;
if(!tmp) return -1;
val = tmp->value;
l->last = tmp->prev;
if(l->last) l->last->next = NULL;
else l->first = NULL;
free(tmp);
return val;
}
int popFront(dblist* l)
{
int val;
elem *tmp = l->first;
if(!tmp) return -1;
val = tmp->value;
l->first = tmp->next;
//if(l->first)l->first->prev = NULL;
//else l->last = NULL;
//free(tmp);
return val;
}
dblist getInterval (dblist const * s)
{
dblist* intervals = NULL;
memmove(&intervals, &l, sizeof(l));
if(intervals->first)intervals->first->prev = NULL;
else intervals->last = NULL;
return *intervals;
}
void View (dblist l)
{
elem *pelem = l.first;
while (Pelem)
{
printf ("% d \ n", pelem-> value);
pelem = pelem-> next;
}
}
void ViewReverse (dblist l)
{
elem* test = l.last;
while (test)
{
printf("% d \ n", test-> value);
test = test-> prev;
}
}
void Clear (dblist * l)
{
elem *tmp;
elem *pelem = l->first;
while(pelem)
{
tmp = pelem;
pelem = pelem->next;
free(tmp);
}
l->first = NULL;
l->last = NULL;
}
的main.c
#include <stdlib.h>
#include <stdio.h>
#include "dblist.h"
int main()
{
dblist pdbListe * = malloc (sizeof (dblist));
dblist interval;
Init (pdbListe);
printf ("Pushin In The gains list\n");
PushFront (pdbListe, 10);
Pushback (pdbListe, 20);
Pushback (pdbListe, 40);
PushFront (pdbListe, 23);
PushFront (pdbListe, 70);
PushFront (pdbListe, 54);
printf ("Viewing the list:\n");
View (pdbListe *);
puts ("--------------");
printf ("poping front capital gains from The Stack:\n");
printf ("% d\n", PopFront (pdbListe));
printf ("% d\n", PopFront (pdbListe));
// Printf ("% d\n", PopBack (pdbListe));
puts ("--------------");
printf ("Viewing the list after pop front:\n");
View (pdbListe *);
puts ("--------------");
printf ("this is pdbListe:% p\n", pdbListe);
printf ("this is interval:% p\n", & interval);
interval = getInterval (pdbListe);
printf ("Viewing the interval\n");
ViewReverse (interval);
printf ("first element is:% d\n", interval.first-> value);
printf ("last element is:% d\n", interval.last-> value);
puts ("--------------");
printf ("Reverse Viewing the list after pop front:\n");
ViewReverse (pdbListe *); // ISSUE HERE: it should print 6 elements not 4
puts ("--------------");
printf ("this is pdbListe:% p\n", pdbListe);
printf ("this is interval:% p\n", & interval);
printf ("sizeof pdbListe% d\n", sizeof (pdbListe));
printf ("sizeof interval% d\n", sizeof (interval));
printf ("Pushing back a value in The List:\n");
Pushback (pdbListe, 30);
printf ("Viewing the list after push back:\n");
View (pdbListe *);
puts ("--------------");
printf ("In The Front popping list:\n");
printf ("% d\n", PopFront (pdbListe));
printf ("% d\n", PopFront (pdbListe));
puts ("--------------");
printf ("Viewing the list after pop front:\n");
View (pdbListe *);
puts ("--------------");
printf ("Clearing the list\n");
Clear (pdbListe);
printf ("Freeing the list\n");
free (pdbListe);
system ("PAUSE");
return 0;
}
不在乎malloc.h,它是我用來確保正確內存usga的小工具
所以問題是間隔變量來自getInterval(const dblist *)
,我希望它只保留一部分當popBack
或popFront
已被應用時的初始列表。
問題是如果我對getInterval
進行修改,它會影響pdbListe
的值。例如嘗試修改getInterval
這樣的(嘗試如下圖所示評論那些行):
dblist getInterval(const dblist* l) {
dblist* intervals = NULL;
memmove(&intervals, &l, sizeof(l));
//if(intervals->first)intervals->first->prev = NULL;
//else intervals->last = NULL;
return *intervals;
}
從那裏可以看出,不僅通過結果返回getInterval
(在這種情況下main.c中的間隔可變)而且也是pdbListe
變量,它本質上不應該被修改!
我能做些什麼來解決這個問題?我希望pdbListe
保持原樣,不會受到getInterval
正在做的事情的影響。
對不起,正確的句子是:「從那裏可以看出,不僅getRange返回的結果(在本例中是main.c中的range變量),而且還有pdbListe變量正在被修改,這本質上不應該是修改!! – CHouse 2010-12-12 19:05:36
有兩件事:你的代碼甚至沒有編譯,因爲一些函數接受一個名字爲「s」的參數,但是試圖使用一個名爲「l」的未聲明變量(當它們表示「s」時)第二,爲什麼你用memmove來複制單個指針?你是否想要複製「l」*指向*的東西? – zwol 2010-12-12 19:13:00
可能代碼沒有編譯,我爲此道歉。花費了大量的編輯來使代碼可讀,所以可能會出現錯誤,但我相信我沒有改變邏輯。那個memcopy是爲了好玩!你可以使用assigment運算符(=),它會很好,在slig後HT代碼修改!謝謝 – CHouse 2010-12-13 00:30:55