概述
malloc函数简介
malloc函数在C语言和C++中经常使用,为变量动态分配内存空间。
函数原型 void malloc(int size)
说明:malloc 向系统申请分配指定size个字节的内存空间。如果分配成功则返回指向被分配内存的指针,否则返回空指针NULL。
该函数包含在头文件:#include <malloc.h>中 ,使用时需导入头文件*<malloc.h>或者<stdlib.h>** 。注意!当内存不再使用时,应使用free()函数将内存块释放。
常见用法
- 在不知道变量需要的确定内存时,比如在定义一个数组时,数组的大小在程序编译后才知道,这时可以用malloc函数。
int main()
{
int n;
scanf("%d",&n);
int *m=(int *)malloc(sizeof(int)*n); //定义了一个指向n个int的 指针变量,相当于开了一个n个int元素的数组。
//如果n很大,超过1000000,那么开一个这么大的int型数组就会发生栈溢出。
int m[1000000]; //会发生栈溢出。
return 0;
}
- 为结构体变量分配空间。
如果定义一个结构体类型的普通变量,可以不malloc动态申请内存,CPU会为这个结构体变量分配内存 。
typedef struct
{
int n;
char *p;
}node;
int main()
{
node a; //定义的是结构体普通变量,可以不使用malloc申请内存,CPU会为这个结构体变量分配内存
a.n=4;
printf("%d",a->n); //可以成功输出
node *b; //定义的是结构体指针变量,CPU会为这个指针开辟内存,大小为4个字节。但是要存储结构体的数据成员这个空间不够,会引发段错误,此时必须要malloc申请一个结构体类型大小的动态内存,存储数据成员。
//b=(node *)malloc(sizeof(node));
printf("%d",sizeof(b)); //用sizeof(b)查看b的大小为4
char p[]="abcd";
printf("%d",b->n);
(a->p)=p;
printf("%c",a->p[0]);
return 0;
}
没有使用malloc为结构体指针变量b分配空间,会报warning: ‘b’ is used uninitialized in this function [-Wuninitialized]|。
- 在定义结构体时需要注意,要依次为其成员分配空间。
在平常使用过程中,在用malloc函数为某个结构体分配空间后,在对其成员变量(指针类型)进行操作,比如 令该指针 p=NULL时,总会报“Program received signal SIGSEGV, Segmentation fault."(程序收到信号SIGSEGV,分段故障).
比如,今天在用邻接顺序表实现一个有向带权图时,就再次报了这个错误“Program received signal SIGSEGV, Segmentation fault."。
#include <stdio.h>
#include <malloc.h>
#define Max 100;
using namespace std;
typedef struct Node //单链表中的每个节点
{
int adjvex; //边表节点中的顶点编号
int weight;
struct Node *next;
}AdjNode;
typedef struct Hnode //单链表的头节点,每一个表头节点存放图中每个点的信息
{
int no;
AdjNode *first;
}AdjHead; //每个顶点的表头节点
typedef struct //图
{
int n,e;
AdjHead *node[Max];
}AdjGraph;
void CreateGraph(AdjGraph *G,int edge[Max][Max],int n,int e)
{
//使用malloc为结构体图G分配空间
G=(AdjGraph *)malloc(sizeof(AdjGraph));
G->n=n;
G->e=e;
for(int i=0;i<n;i++)
{
//思考为什么还要用malooc为G->node[i](每个表头)分配空间?
//如果不写,调试时会报Program received signal SIGSEGV, Segmentation fault."
G->node[i]=(AdjHead *)malloc(sizeof(AdjHead));
G->node[i]->first=NULL; //先把每个表头节点置为空
G->node[i]->no=i;
AdjNode *p;
for(int j=n-1; j>0;j--)
{
if(edge[i][j]!=0 && edge[i][j]!=INF)
{
p=(AdjNode *)malloc(sizeof(AdjNode));
p->adjvex=j;
p->weight=edge[i][j];
p->next=G->node[i]->first;
G->node[i]->first=p; //头插法建立单链表
}
}
}
printf("创建成功!n");
}
//说明:在main()函数里已经使用 G2=(AdjGraph *)malloc(sizeof(AdjGraph));为G分配了空间。
疑问:不是函数里已经使用 G=(AdjGraph *)malloc(sizeof(AdjGraph))分配了空间嘛?为什么还要使用 malloc函数为每个表头节点分配空间,才能对表头节点G->node[i]内部的指针成员变量进行置空操作?
回答:因为G=(AdjGraph *)malloc(sizeof(AdjGraph))只是为n,e,和node[max]这个数组分配了空间,数组里面存放的是结构体类型的指针,指针只占4个字节(32位CPU),而该指针指向的变量为AdjHead类型(结构体),该类型变量所占用的空间不只4个字节,所以对该变量进行操作时还需要动态分配空间。
总结:如果定义一个结构体类型的普通变量,可以不malloc动态申请内存,CPU会为这个结构体变量分配内存 。
如果定义的是一个结构体的指针,CPU会为这个指针开辟内存,但是此时这个大小是4(32位的CPU),该空间的大小不够存储数据成员,所以在使用该结构体数据成员时,还要malloc申请相应结构体类型大小的动态内存,用于数据成员存储使用。
最后
以上就是纯情鞋子为你收集整理的在使用malloc函数时遇见的常见错误的全部内容,希望文章能够帮你解决在使用malloc函数时遇见的常见错误所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
发表评论 取消回复