【代码纠错】 (指针操作/内存分配与释放)

本文详细解析了C语言中动态内存分配与释放的常见错误,包括结构体数组内存分配不足、成员变量未分配内存及内存泄露问题。通过修改代码,展示了如何正确地为结构体数组分配内存,为成员变量分配并检查内存,以及如何避免内存泄露。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

 

题目代码(找错误)

一、15行分配内存没有*NUM,这里目的应该是给一个结构体数组赋值

二、20行给单个结构体的pname赋值的时候没有事先分配内存,并且检查非空

三、程序没有考虑到释放内存,而释放内存需要

完整正确代码如下


题目代码(找错误)

#include<stdio.h>
#include<string.h>
#include<malloc.h>

typedef struct student {
    char* pname;
    int nID;
}strctstu;      
#define NUM 5
void main()
{
    strctstu* pstu;
    int i;
    char name[10];
    pstu = (strctstu*)malloc(sizeof(strctstu));
    for (i = 0; i < NUM; i++)
    {
        scanf("%d", &pstu->nID);
        scanf("%s", name);
        strcpy(pstu->pname, name);
        pstu++;
    }
}

 

 

一、15行分配内存没有*NUM,这里目的应该是给一个结构体数组赋值

 

pstu = (strctstu*)malloc(sizeof(strctstu));

 

应改为

 

pstu = (strctstu*)malloc(sizeof(strctstu) * NUM);

 

 

二、20行给单个结构体的pname赋值的时候没有事先分配内存,并且检查非空

 

 strcpy(pstu->pname, name);

 

应改为

 

        pstu->pname = (char*)malloc(10);

		if (pstu->pname == NULL)
		{
			free(pstu);
			printf("Error!\n");
		}
		strcpy(pstu->pname, name);

 

 

三、程序没有考虑到释放内存,而释放内存需要

1 把指针指向结构体数组开头,所以需要再定义一个结构体指针用于存放指向开头的指针

 

strctstu* pstu, *pstubackup;

 

2 释放内存时应该先将结构体数组中的每个结构体的pname free掉,并且将pname指针置为NULL(将开头指针的值赋给pstu,通过pstu++操作每一个结构体)

 

pstu = pstubackup;

	if (pstu)
	{
		for (i = 0; i < NUM; i++)
		{
			if (pstu->pname)
			{
				free(pstu->pname);
				pstu->pname = NULL;
			}
			pstu++;
		}

 

3 将开头指针指向的结构体数组free掉,然后将pstu和这个指针本身置空

 

        free(pstubackup);
		pstubackup = NULL;
		pstu = NULL;

 

 


 

完整正确代码如下

(char数组的输入仍然有小问题,超过10个会出问题)

 

#include<stdio.h>
#include<string.h>
#include<malloc.h>

typedef struct student {
	char* pname;
	int nID;
}strctstu;

#define NUM 5


void main()
{
	strctstu* pstu, *pstubackup;
	int i;
	char name[10];

	pstu = (strctstu*)malloc(sizeof(strctstu) * NUM);

	if (pstu == NULL)
		return;

	pstubackup = pstu;

	for (i = 0; i < NUM; i++)
	{
		scanf("%d", &pstu->nID);
		scanf("%s", name);
		pstu->pname = (char*)malloc(10);

		if (pstu->pname == NULL)
		{
			free(pstu);
			printf("Error!\n");
		}
		strcpy(pstu->pname, name);
		pstu++;
	}

	pstu = pstubackup;

	if (pstu)
	{
		for (i = 0; i < NUM; i++)
		{
			if (pstu->pname)
			{
				free(pstu->pname);
				pstu->pname = NULL;
			}
			pstu++;
		}

		free(pstubackup);
		pstubackup = NULL;
		pstu = NULL;

	}
}

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值