Linux C 学习 单向链表
2016-06-18 23:54
459 查看
最近从Linux C数据结构和算法学起,下面是一个单向链表的写法,代码如下:
[cpp] view
plain copy
#include <stdio.h>
#include <malloc.h>
int n=0;
typedef struct code
{
int data;
struct code *next;
}List;
List *creatlink()
{
List *head;
List *p1;
List *p2;
head=NULL;
p1=(List *)malloc(sizeof(List));
p2=(List *)malloc(sizeof(List));
printf("Please print the data you want:(end is 0)\n");
scanf("%d",&p1->data);
while(p1->data!=0)
{
n++;
if(n==1)
{
head=p1;
}
else
{
p2->next=p1;
}
p2=p1;
p1=(List *)malloc(sizeof(List));
scanf("%d",&p1->data);
// printf("\n%d\n",p1->data);
}
free(p1);
p2->next=NULL;
return(head);
}
void Print(List *head)
{
List *p;
p=head;
if(head!=NULL)
do
{
printf("[%d]->",p->data);
p=p->next;
}
while(p!=NULL);
printf("\nover!\n");
}
int main()
{
List *head;
head=creatlink();
Print(head);
return(0);
}
结果如下:
![](http://img.blog.csdn.net/20151117210327418?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQv/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
单向链表建立容易犯错误的是这一块:
if(n==1)
{
head=p1;
}
else
{
p2->next=p1;
}
p2=p1;
p1=(List *)malloc(sizeof(List));
scanf("%d",&p1->data);
// printf("\n%d\n",p1->data);
}
先判定头指针,然后再重新为p1申请一片内存,来存放下一个链表里的内容
malloc()最容易出现的问题是内存泄露,所以一定要记得free();
下面有个例子:
兄弟问:" free(p);p=NUll;",为啥free(p)之后,还要置p=NULL呢?有必要么?
free(p)只是将p指向的空间释放掉了,但是p并不等于NULL;
code:
int main()
{
int *p;
p = (int *)malloc(sizeof(int) * 10);
printf("before free: p=%p\n",p);
free(p);
printf("after free: p = %p\n",p);
printf("%d\n",p[0]);
p=NULL;
printf("%d\n",p[0]);
}
result:
before free: p=0x8fa7008
after free: p = 0x8fa7008
0
段错误
也就是p虽然有值,但其指向的空间已经被释放掉了。如果在后续的code中再用到p,就会出现错误,而这种错误是不太明显的。如果显式的置为null的话,就可以使错误马上显现出来。从而避免了调试程序中种种诡异的麻烦。
结论:
如果在程序中free(p)之后,p不会再用,则令p=NULL无所谓。
如果在程序中free(p)之后,p还会用到,则令p=NULL,还原p为纯净的变量,便于以后差错。
[cpp] view
plain copy
#include <stdio.h>
#include <malloc.h>
int n=0;
typedef struct code
{
int data;
struct code *next;
}List;
List *creatlink()
{
List *head;
List *p1;
List *p2;
head=NULL;
p1=(List *)malloc(sizeof(List));
p2=(List *)malloc(sizeof(List));
printf("Please print the data you want:(end is 0)\n");
scanf("%d",&p1->data);
while(p1->data!=0)
{
n++;
if(n==1)
{
head=p1;
}
else
{
p2->next=p1;
}
p2=p1;
p1=(List *)malloc(sizeof(List));
scanf("%d",&p1->data);
// printf("\n%d\n",p1->data);
}
free(p1);
p2->next=NULL;
return(head);
}
void Print(List *head)
{
List *p;
p=head;
if(head!=NULL)
do
{
printf("[%d]->",p->data);
p=p->next;
}
while(p!=NULL);
printf("\nover!\n");
}
int main()
{
List *head;
head=creatlink();
Print(head);
return(0);
}
结果如下:
单向链表建立容易犯错误的是这一块:
if(n==1)
{
head=p1;
}
else
{
p2->next=p1;
}
p2=p1;
p1=(List *)malloc(sizeof(List));
scanf("%d",&p1->data);
// printf("\n%d\n",p1->data);
}
先判定头指针,然后再重新为p1申请一片内存,来存放下一个链表里的内容
malloc()最容易出现的问题是内存泄露,所以一定要记得free();
下面有个例子:
兄弟问:" free(p);p=NUll;",为啥free(p)之后,还要置p=NULL呢?有必要么?
free(p)只是将p指向的空间释放掉了,但是p并不等于NULL;
code:
int main()
{
int *p;
p = (int *)malloc(sizeof(int) * 10);
printf("before free: p=%p\n",p);
free(p);
printf("after free: p = %p\n",p);
printf("%d\n",p[0]);
p=NULL;
printf("%d\n",p[0]);
}
result:
before free: p=0x8fa7008
after free: p = 0x8fa7008
0
段错误
也就是p虽然有值,但其指向的空间已经被释放掉了。如果在后续的code中再用到p,就会出现错误,而这种错误是不太明显的。如果显式的置为null的话,就可以使错误马上显现出来。从而避免了调试程序中种种诡异的麻烦。
结论:
如果在程序中free(p)之后,p不会再用,则令p=NULL无所谓。
如果在程序中free(p)之后,p还会用到,则令p=NULL,还原p为纯净的变量,便于以后差错。
相关文章推荐
- Linux环境下段错误的产生原因及调试方法小结
- Linux内核代码风格
- Linux C学习--getline()函数
- Linux下静态IP地址的设置及TFTP服务的搭建
- samba映射Linux文件夹到windows无密码访问
- Linux0.11内核--进程调度分析之2.调度
- Linux C 函数指针应用---回调函数
- linux内核启动mtdblock0 (driver?)的解决方法
- linux线程同步和进程同步的区别
- Linux C 深入分析结构体指针的定义与引用
- Linux C 内存管理
- Linux 应用---make及makefile的编写
- Linux C 中断言assert()使用简介
- 从头学习linux C 冒泡法排序
- linux C 学习 简单字符串逆序输出
- CentOS关闭图形界面(x window)
- Linux 常用到的功能及命令-FAQ
- 正则表达式理解
- ArchLinux 下文件描述符
- Linux C学习---递归函数