C 结构体指针malloc分配问题

本文探讨了C语言中结构体指针使用时的内存分配问题,包括未分配内存导致的段错误及结构体内指针成员的内存管理。通过示例代码解释了如何正确为结构体及指针成员分配和释放内存,强调了初始化指针和避免内存泄漏的重要性。
摘要由CSDN通过智能技术生成

C语言中关于结构体指针的内存分配问题

话不多说先上一段代码

typedef struct stu
{
	char filename[100];
	char *name;
}stu;
int main()
{
	stu *st;
	strcpy(st->filename,"dsssssddd");
	strcpy(st->name,st->filename);
	printf("%s\n%s",st->name,st->filename)return 0;
}

熟悉的小伙伴一眼应该就可以看出哪里出错了,对就是我们常说的结构体指针的内存分配的问题,既然分配出错我们对其分配内存就好了,于是有了以下代码。

typedef struct stu
{
	char filename[100];
	char *name;
}stu;
int main()
{
	stu *st;
	st=(stu *)malloc(sizeof(stu));
	strcpy(st->filename,"dsssssddd");
	strcpy(st->name,st->filename);
	printf("%s\n%s",st->name,st->filename);
	free(st);	
   return 0;
}

这样是不是就没问题,所以我们将代码运行一番。

run: line 1:     3 Segmentation fault      (core dumped) ./a.out
Exited with error status 139

想法是对的,但结果却出现的偏差,问题就出在我们结构体中的指针类型也需要分配空间,当然除非你的指针指向文字常量区,但那样就属于把char *给初始化了。也就是我们无法对其进行修改了。

st->name="8554"; //OK
strcpy(st->name,"9999"); //error

就会再次发生上面同样的错误
说了这么久的常见错误,是时候写一下正确的示范了

typedef struct stu
{
	char filename[100];
	char *name;
}stu;
int main()
{
	stu *st;
	st=(stu *)malloc(sizeof(stu));
	st->name=(char*)malloc(sizeof(char)*20);
	strcpy(st->filename,"77777");
	strcpy(st->name,"fffff");
	printf("%s\n%s\n",st->name,st->filename);
	
	strcpy(st->name,st->filename);
	printf("%s\n%s\n",st->name,st->filename);
    free(st->name);
	free(st);	
   return 0;
}

来让我们看一下运行结果

fffff
77777
77777
77777

我们不仅需要对结构体指针分配空间,还需要对结构体内部的指针分配空间;
为此我们在做一个小实验,我们对name分配空间之后,是否还可以进行初始化操作,又是否需要free掉开辟的堆空间

	stu *st;
	st=(stu *)malloc(sizeof(stu));
	st->name=(char*)malloc(sizeof(char)*20);
	strcpy(st->filename,"77777");
	strcpy(st->name,"fffff");
	printf("%s\n%s\n",st->name,st->filename);
	st->name="66666";
	printf("%s\n%s\n",st->name,st->filename);
    free(st->name);
	free(st);	

将上面的代码运行后,将会出现
**free(): invalid pointer **这个错误,说明我们free了一个无效的指针
但是我们把free(st->name)删除之后,我们重新运行结果却又正确
结论: 我们malloc是把数据存储在堆空间中需要进行手动的释放,但是我们把name初始化是将数据放在了文字常量区,它是跟随程序结束后自动释放的,当我们对char 进行初始化指向了文字常量,那么我们就不可以在对其进行修改的操作,相当于const char name =“66666”;不能在对其进行修改。

stu *st;
	st=(stu *)malloc(sizeof(stu));
	st->name=(char*)malloc(sizeof(char)*20);
	strcpy(st->filename,"77777");
	strcpy(st->name,"fffff");
	printf("%s\n%s\n",st->name,st->filename);
	free(st->name);//释放掉name
	st->name="66666";//重新初始化
	printf("%s\n%s\n",st->name,st->filename);
	free(st);	

那么我们在重新初始化需要将我们开辟的堆空间先释放掉,避免我们开启的堆空间没有了主人,导致内存泄漏。这很重要,养成好习惯!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值