当前位置 : 主页 > 编程语言 > c语言 >

动态内存访问

来源:互联网 收集:自由互联 发布时间:2023-09-06
#define _CRT_SECURE_NO_WARNINGS 1 #includestdio.h#includestdlib.h#includestring.h#includeerrno.h//栈区:局部变量,局部数组,函数的形式参数//堆区:动态内存分配//静态区:全局变量,静态变量 全局数组

#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h> #include<stdlib.h> #include<string.h> #include<errno.h> //栈区:局部变量,局部数组,函数的形式参数 //堆区:动态内存分配 //静态区:全局变量,静态变量 全局数组 statint int a=10;

//如果不想浪费空间,了解创建变长数组

//动态内存分配 //1.malloc //2.free //3.calloc //4.realloc

//int main() //{ //int *p = (int *)malloc(10 * sizeof(int));//需要强制类型转换一下 ////malloc(这里不能为0) ////如果出现空间不够的情况下,会出现一个空指针。 //if (p == NULL) //{ // printf("%s\n", strerror(errno)); //} //else //{ // //正常使用空间 // int i = 0; // for (i = 0; i < 10; i++) // { // *(p + i) = i; // } // for (i = 0; i < 10; i++) // { // printf("%d", *(p + i)); // } //} ////当动态申请的空间不再使用的时候 //////就应该还给操作系统

////这里如果p指向的空间不是动态开辟的,那free函数的行为是未定义的
////如果p是空指针,则函数什么事都不做
//free(p);//p虽然被释放了,但还是有能力找到这块空间,所以附成空指针
////当再不需要这块空间之后,就放弃它
//p = NULL;

//malloc(10*sizeof(int))//修改总字节  效率高,但不初始化
//calloc效率低,但是初始化
//int*p = (int*)calloc(10, sizeof(int));//修改元素数,元素的大小
//	//如果出现空间不够的情况下,会出现一个空指针。
//if (p == NULL)
//{
//	printf("%s\n", strerror(errno));
//}
//else
//{
//	//正常使用空间
//	int i = 0;
//	//for (i = 0; i < 10; i++)
//	//{
//	//	*(p + i) = i;
//	//}
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d", *(p + i));
//	}
//}
////释放空间
////free函数是用来释放动态空间
//free(p);
//p = NULL;


//reallor//调整动态开辟内存的大小
//void* realloc(void* ptr,size_t size)
	//ptr是要调整内存地址
	//size 调整之后新大小
	//返回值为调整之后的内存起始位置
	//调整内存又来两种情况
	//1.原有空间足够大
	//2.后续空间不够扩展

//注意事项:
//1.如果p指向的空间之后有足够的内存空间可以追加,则直接追加,后返回p
//2.如果p指向的空间之后没有足够的内存空间可以追加,则realloc函数会重新找一个新的内存空间
//开辟一块满足需求的空间,并且把原来内存中的数据拷贝回来,释放旧的内存空间,最后返回新开辟的内存空间地址
//3.得用一个新的变量来接受realloc的返回值
//int* ptr = realloc(p, INT_MAX);
//if (ptr != NULL)//防止失败丢弃原来空间
//{
//	p = ptr;
//}
//int* p2 = realloc(p, 40);
//int i = 0;
//for (i = 5; i < 10; i++)
//{
//	*(p + i) = i;
//}
//for (i = 0; i < 10; i++)
//{
//	printf("%d ", *(p2 + 1));
//}

//常见动态内存错误
//1.对空指针的解应用操作
	//int *p = (int *)malloc(10 * sizeof(int));//需要强制类型转换一下

//没有分析malloc失败的情况 // int i = 0; // for (i = 0; i < 10; i++) // { // *(p + i) = i; // } // for (i = 0; i < 10; i++) // { // printf("%d", *(p + i)); // }

//2.对动态开辟空间的越界访问
	//int *p = (int *)malloc(5 * sizeof(int));//需要强制类型转换一下
//if (p == NULL)
//{
//	printf("%s\n", strerror(errno));
//}
//else
//{
//	//正常使用空间
//	int i = 0;
//	for (i = 0; i < 10; i++)//上面只申请了20个字节
//	{
//		*(p + i) = i;
//	}
//	for (i = 0; i < 10; i++)
//	{
//		printf("%d", *(p + i));
//	}

//3.对非动态开辟内存使用free释放
//int a = 10;//放在栈区
//int*p = &a;
//*p = 20;
//free(p);//在堆区上开辟
//p = NULL;

//4.使用free释放动态开辟内存的一部分
//int *p = (int*)malloc(40);
//if (p == NULL)
//{
//	return 0;
//}
//int i = 0;
//for (i = 0; i < 10; i++)
//{
//	*p++ = i;
//}
//free(p);
//p = NULL;

//5.对同一块内存多次释放
//int *p = (int*)malloc(40);
//if (p == NULL)
//{
//	return 0;
//}
//使用
//释放
//free(p);
//p=NULL;
////.....
//free(p);

//6.动态开辟内存忘记释放(内存泄漏)
//while(1)
//{
//malloc(1)
//}

//void Getemory(char *p)//p是形参,是str的一份临时拷贝
//	//空间开辟是开辟在P里面,不是开辟在str里面
//	//存放的数字相同,存放的空间不同
//{
//	p = (char *)malloc(100);
//}

//void Text(void)
//{
//	char *str = NULL;
//	GetMemory(str);
//	strcpy(str, "hello world");//空指针就是0,追加到非法空间,导致非法访问,程序崩溃
//	printf(str);
//}

//int main()
//{
//	Test();
//}

//改正1
//void GetMemory(char **p)//2级指针
//{
//	*p = (char*)malloc(100);
//}

//void Test(void)
//{
//	char *str = NULL;//一级指针
//	GetMemory(&str);//传地址,char**才能接收
//	strcpy(str, "hello world");
//	printf(str);

//	free(str);
//	str = NULL;
//}

//int main()
//{
//	Test();
//	return 0;
//}

	//改正2
//char GetMemory(char *p)
//{
//	p = (char*)malloc(100);

//return p; //}

//void Test(void)
//{
//	char *str = NULL;
//	str=GetMemory(str);
//	strcpy(str, "hello world");
//	printf(str);

//free(str); //str = NULL;

//	free(str);
//	str = NULL;
//}

//int main()
//{
//	Test();
//	return 0;
//}


//char *GetMemory(void)
//{
//	char p[] = "hello world";//在栈空间上开辟空间
//	return p;
//}
//void Test(void)
//{
//	char *str = NULL;
//	str = GetMemory();//p里面的是hello world 用完之后就释放了
//	//再次访问不知道变成什么了,非法访问
//	printf(str);
//}

//int main()
//{
//	Test();
//}

//int * test()//错误
//{
//	int a = 10;
//	return &a;//在栈区上开辟空间
//}

//int main()
//{
//	int *p = test();//也是非法访问
//	*p = 20;

//}

//int * test()//正确
//{
//	static int a = 10;//static修饰代码生命周期延长不销毁,开辟的空间放到静态区了
//	return &a;//在栈区上开辟空间
//}

//int main()
//{
//	int *p = test();//也是非法访问
//	*p = 20;

//}

//int* test()
//{
//	int *ptr = malloc(100);//堆空间申请的内存只有free才能回收
//	return ptr;
//}

//int main()
//{
//	int *p = test();
//}

//int *f2(void) //{ // int *ptr;//野指针 // *ptr = 10; // return ptr; //}

//void GetMemory(char **p, int num) //{ // *p = (char )malloc(num); //} //void Test(void) //{ // charstr = NULL; // GetMemory(&str, 100); // strcpy(str, "hello"); // printf(str); // //改 // free(str);//如果不写则造成内存泄漏 // str = NULL; //} // //int main() //{ // Test(); //} // return 0; //}

//void Test(void) //{ // char*str = (char *)malloc(100); // strcpy(str, "hello"); // free(str);//free释放之后,并不会把str置为NULL // str = NULL; // if (str != NULL) // { // strcpy(str, "world"); // printf(str); // } //}

//int main() //{ // Test(); //}

//柔性数组 //结构中最后一个元素是未知大小的数组,这就叫[柔性数组]的成员

//柔性数组的使用 //struct S //{ // int n; // int arr[0];//未知大小的-柔性数组成员-数组大小是可以变化的 //}; // //int main()//malloc和realloc共同配合使用 //{ //// struct S s; ////printf("%d\n",sizeof(s)); //struct S* ps = (struct S*)malloc(sizeof(struct S) + 5 * sizeof(int)); //ps->n = 100; //int i = 0; //for (i = 0; i < 5; i++) //{ // ps->arr[i] = i; //} //struct S*ptr = realloc(ps, 44);//对整个结构体变大小 //if (ptr != NULL) //{ // ps = ptr; //} //for (i = 5; i < 10; i++) //{ // ps->arr[i] = i; //} //for (i = 0; i < 10; i++) //{ // printf("%d ", ps->arr[i]); //} //free(ps); //ps=NULL; // //

// return 0; //}

struct S { int n; int *arr;//放一个地址 };

int main()//malloc和realloc共同配合使用 { struct S* ps = (struct S*)malloc(sizeof(struct S)); ps->arr = malloc(5 * sizeof(int));//申请的地址放到arr里面去 //两次malloc风险较大,释放注意先后顺序, //两次开辟的空间不连续,访问效率低一些 int i = 0; for (i = 0; i < 5; i++) { ps->arr[i] = i;//arr数组名代表首元素地址 }

for (i = 0; i < 5; i++)
{
	printf("%d ", ps->arr[i]);
}
int *ptr = realloc(ps->arr, 10 * sizeof(int));//把arr弥补成10个整形的大小
if (ptr != NULL)//对arr这个指针指向的数组变大小
{
	ps->arr = ptr;
}
for (i = 5; i < 10; i++)
{
	ps->arr[i] = i;
}
for (i = 0; i < 10; i++)
{
	printf("%d ", ps->arr[i]);
}
free(ps->arr);
ps->arr = NULL;
free(ps);
ps= NULL;

//柔性数组的好处:1方便释放内存,2有利于访问速度
return 0;

}

网友评论