一、內存洩露
1、正常的鏈表操作
下面程序建立一個10元素的鏈表,輸出它們的節點,每個節點是一個員工的工號和年齡。最後刪除每個節點,釋放列表。
dp@dp:~/memorytest % cat 1.c
#include
#include
typedef struct listnode mynode;
struct listnode{
mynode *next;
int number;
int age;
};
mynode *addnode(mynode *prevnd,int number,int age){
mynode *ndtemp=(mynode*)malloc(sizeof(mynode));
prevnd->next=ndtemp;
ndtemp->number=number;
ndtemp->age=age;
ndtemp->next=NULL;
return ndtemp;
}
mynode *initlist(){
mynode *temp=(mynode*)malloc(sizeof(mynode));
temp->number=0;
temp->age=0;
temp->next=NULL;
return temp;
}
int main(){
mynode *mylist=initlist();
mynode *mytempnd=mylist;
int i=0;
for(i=0;i<10;i++){
mytempnd=addnode(mytempnd,i,20+i);
}
//下面是正常的鏈表操作
//先輸出鏈表元素
for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){
printf("id:%d,age:%d\n",mytempnd->number,mytempnd->age);
}
//然後刪除鏈表中的所有元素
for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){
printf("delete id:%d\n",mytempnd->number);
free(mytempnd);
}
free(mylist);
return 0;
}
下面是程序運行效果
dp@dp:~/memorytest % ./mytest
id:0,age:20
id:1,age:21
id:2,age:22
id:3,age:23
id:4,age:24
id:5,age:25
id:6,age:26
id:7,age:27
id:8,age:28
id:9,age:29
delete id:0
delete id:1
delete id:2
delete id:3
delete id:4
delete id:5
delete id:6
delete id:7
delete id:8
delete id:9
下面演示了垃圾的形成,這是內存洩露的一種方式,即在鏈表中,某些節點與鏈表中的其它節點失去聯系,導致無法刪除,下面故意讓第4個結點的next指針指向null,失去與後面6個元素的聯系。
dp@dp:~/memorytest % cat 1.c
#include
#include
//code:[email protected]
//author:myhaspl
//date:2014-01-10
typedef struct listnode mynode;
struct listnode{
mynode *next;
int number;
int age;
};
mynode *addnode(mynode *prevnd,int number,int age){
mynode *ndtemp=(mynode*)malloc(sizeof(mynode));
prevnd->next=ndtemp;
ndtemp->number=number;
ndtemp->age=age;
ndtemp->next=NULL;
return ndtemp;
}
mynode *initlist(){
mynode *temp=(mynode*)malloc(sizeof(mynode));
temp->number=0;
temp->age=0;
temp->next=NULL;
return temp;
}
int main(){
mynode *mylist=initlist();
mynode *mytempnd=mylist;
int i=0;
for(i=0;i<10;i++){
mytempnd=addnode(mytempnd,i,20+i);
}
//下面是正常的鏈表操作
//先輸出鏈表元素
for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){
printf("id:%d,age:%d\n",mytempnd->number,mytempnd->age);
}
//然後刪除鏈表中的所有元素
for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){
printf("delete id:%d\n",mytempnd->number);
free(mytempnd);
}
free(mylist);
//下面是形成內存洩露第一種情況-垃圾的演示
//生成並輸出鏈表,這個與前面相同
mylist=initlist();
mytempnd=mylist;
i=0;
for(i=0;i<10;i++){
mytempnd=addnode(mytempnd,i,20+i);
}
for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){
printf("id:%d,age:%d\n",mytempnd->number,mytempnd->age);
}
//刪除鏈表,我們故意留下後面6個鏈表節點無法刪除,導致後面6個鏈表節點形成垃圾
int j=0;
for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){
if (++j>3){
mytempnd->next=NULL;
break;
}
}
for (mytempnd=mylist->next;mytempnd!=NULL;mytempnd=mytempnd->next){
printf("delete id:%d\n",mytempnd->number);
free(mytempnd);
j++;
}
return 0;
}
下面是程序運行效果
dp@dp:~/memorytest % gcc 1.c -o mytest
dp@dp:~/memorytest % ./mytest
id:0,age:20
id:1,age:21
id:2,age:22
id:3,age:23
id:4,age:24
id:5,age:25
id:6,age:26
id:7,age:27
id:8,age:28
id:9,age:29
delete id:0
delete id:1
delete id:2
delete id:3
delete id:4
delete id:5
delete id:6
delete id:7
delete id:8
delete id:9
id:0,age:20
id:1,age:21
id:2,age:22
id:3,age:23
id:4,age:24
id:5,age:25
id:6,age:26
id:7,age:27
id:8,age:28
id:9,age:29
delete id:0
delete id:1
delete id:2
delete id:3
dp@dp:~/memorytest %