Android JNI系列(3)——c语言基础(动态内存分配、字符串)

    本博客的原创文章,都是本人平时学习所做的笔记,不做商业用途,如有侵犯您的知识产权和版权问题,请通知本人,本人会即时做出处理删除文章。

  • 动态内存分配

c语言的内存分为:1.栈区(stack),2.堆区(heep),3.全局区或静态区,4.字符常量区,5.程序代码区。

栈区:自动分配和释放。windows下,栈内存分配2M(确定的常数),超出了限制,提示Stack overflow错误,栈溢出。

堆区:程序员手动分配和释放。可以给应用程序分配80%的内存。

void main(){
	//静态内存分配 Stack overflow错误,栈溢出
	//栈内存
	int a[1024 * 1024 * 10];
	getchar();
}
//堆内存
void main(){
	//在堆内存上,分配40M的内存
	int *p=malloc(1024*1024*40);
	//释放堆内存
	free(p);
	getchar();
}
  • 动态创建数组

在程序运行过程中,可以随意的开辟指定大小的内存,以供使用。

//创建一个数组,动态指定数组大小
void main(){
	//静态内存分配创建数组,数组的大小是固定的
	int a[10];

	int len;
	printf("输入数组的长度:");
	scanf("%d",&len);

	//开辟内存,大小len*4字节
	int *p=malloc(len*sizeof(int));
	//p是数组的首地址,p就是数组的名称
	//给数组元素赋值(使用这块刚刚开辟出来的内存区域)
	int i = 0;
	for (; i < len; i++)
	{
		p[i] = rand() % 100;	
		printf("%d,%#x\n",p[i],&p[i]);
	}
	//手动释放内存
	free(p);
	getchar();
}
  • 静态内存分配和动态内存分配的区别

静态内存分配:分配内存得大小是固定的,缺点:1.很容易超出栈内存的最大值。2.为了防止内存不够用往往开辟更多的内存,容易浪费内存。

动态内存分配:在程序运行过程中,动态指定需要使用的内存大小,手动释放,释放之后这些内存还可以被重新使用(活水)。 

  • 动态内存重新分配 

realloc()重新分配内存 ,参数:1.原来内存的指针,2.内存扩大之后的总大小。

缩小:缩小的那一部分数据会丢失。

扩大:内存是连续的

          1.如果当前内存段后面有需要的的内存空间,直接扩展这段内存空间,realloc返回原指针。

          2.如果当前内存段后面的空间不够,那么就使用堆中的第一个能够满足这一要求的内存块,将目前的数据复制到新的位置,并将原来的数据块释放掉,返回新的内存地址。

          3.如果申请失败,返回NULL,原来的指针仍然有效。

void main(){
	//静态内存分配创建数组,数组的大小是固定的
	int a[10];

	int len;
	printf("输入数组的长度:");
	scanf("%d",&len);

	//开辟内存,大小len*4字节
	int *p=malloc(len*sizeof(int));
	//p是数组的首地址,p就是数组的名称
	//给数组元素赋值(使用这块刚刚开辟出来的内存区域)
	int i = 0;
	for (; i < len; i++)
	{
		p[i] = rand() % 100;	
		printf("%d,%#x\n",p[i],&p[i]);
	}

	int addlen;
	printf("输入数组增加的长度:");
	scanf("%d", &addlen);
	//内存不够用,扩大刚刚分配的内存空间
	//参数:1.原来内存的指针2.内存扩大之后的总大小
	int* p2=realloc(p, sizeof(int)*(len + addlen));
	if (p2 == NULL){
		printf("内存分配失败");
	}
	//重新赋值
	 i = 0;
	for (; i < len+addlen; i++)
	{
		p2[i] = rand() % 100;
		printf("%d,%#x\n", p2[i], &p2[i]);
	}

	//手动释放内存 不能多次释放
	if (p != NULL){ 
		free(p); 
		p = NULL;
	}
	if (p2 != NULL){
		free(p2);
		p2 = NULL;
	}
	getchar();
}
  •  内存分配需要注意的细节

1.不能多次释放

2.释放之后,给指针置NULL,标志释放完成

3.内存泄漏(p重新赋值之后,再free,并没有真正释放内存),应该重新赋值之前先释放。

void main(){
	int* p=malloc(1024 * 1024 * 40);
	free(p);//如果这里没有释放就会内存泄漏
	p = malloc(1024 * 1024 * 40);
	free(p);
	getchar();
}
  •  字符串
//使用字符数组来存储字符串
void main(){
	// ‘\0’结束符 没有会有乱码
	char s[] = { 'c', 'h','i', 'n', 'a' ,'\0'};
	//比实际位数多一位,多出的一位‘\0’
	char s1[6] = { 'c', 'h', 'i', 'n', 'a' };
	char str[10] = "china";
	//可以被修改的
	str[0] = 's';
	printf("%s\n", s);
	printf("%s\n", s1);
	printf("%s\n", str);
	getchar();
}
//字符指针
void main(){
	//内存连续排列  不可修改
	char* p = "hello";
	printf("%s\n", p);
	getchar();
}
//在一个串中查找给定字符的第一个匹配处
void main(){
	char *str = "i want to china";
	char* p = strchr(str, 'c');
	if (p){
                //p是字符索引位置,str是首地址索引位置
		printf("索引位置:%d\n",p-str);
	}
	else{
		printf("没有找到");
	}
	system("pause");
}
//stract字符串拼接函数
void main(){
	char dest[50];
	char *a = "china";
	char *b = " is powerful!";
	strcpy(dest,a);//先把a赋值到数组里面
	strcat(dest, b);//在和b拼接
	printf("%s\n",dest);
	system("pause");
}
//在一个串中查找给定字符串的第一个匹配处
void main(){
	char *str = "i want to china";
	char *a = "to";
	char* p = strstr(str, a);
	if (p){
		printf("索引位置:%d\n",p-str);
	}
	else{
		printf("没有找到");
	}
	system("pause");
}

------------------------------------------------       

    想要继续跟我一起学习一起成长,请关注我的公众号:程序员持续发展方案

你可能感兴趣的:(JNI,动态内存分配,c语言基础,jni,字符串,释放内存)