JNI入门之C/C++基础三

1.3动态内存分配 字符串

1.3.1几个内存区域

1.栈区(stack)

         windows下,栈内存分配2M(确定的常数),超出了限制,提示stackoverflow错误

         自动分配,释放

2.堆区(heap)

         程序员手动分配释放,操作系统80%内存

3.全局区或静态区

4.字符常量区

5.程序代码区

1.3.2 动态分配内存

方法:void *malloc(unsigned size);

在堆内存开辟一定大小的内存.

参数列表: 内存大小单位是字节

返回值: 堆内存指针

方法: void free(void *ptr);

动态释放内存

参数列表: 堆内存指针

 

创建动态数组示例:

创建一个数组,动态指定数组的大小

(在程序运行过长中,可以随意的开辟指定大小的内存,以供使用,相当于Java中的集合)

 

void main(){

         //静态内存分配创建数组,数组的大小必须是固定的,也就是说数组大小必须是常量

         //int i = 10;

         //int a[i];

 

         int len;

         printf("输入数组的长度:");

         scanf("%d",&len);

 

         //开辟内存,大小len*4字节

         int* p = malloc(len * sizeof(int));

         //p是数组的首地址,p就是数组的名称(数组就是连续的内存区域)

         //给数组元素赋值(使用这一块刚刚开辟出来的内存区域)

         int i = 0;

         for (; i < len - 1; i++){

                   p[i] = rand() % 100;

                   printf("%d,%#x\n", p[i], &p[i]);

         }

        

         //手动释放内存

         free(p);

         getchar();

}

 

1.3.3 静态内存分配与动态内存分配

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

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

 

方法 void *realloc(void *ptr, unsignednewsize);

对ptr地址的内存区域重新分配空间,

参数列表: 1.原来内存的指针 2.内存扩大之后的总大小

返回值: 重新分配后的内存区域的指针

重新分配内存的几种情况:

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

扩大,(连续的)

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

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

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

 

重新分配内存示例:

void main(){

         int len;

         printf("第一次输入数组的长度:");

         scanf("%d", &len);

 

         int* p = malloc(len * sizeof(int));    

         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;

         printf("--------------------------\n");

         for (; i < len + addLen; i++){

                   p2[i] = rand() % 200;

                   printf("%d,%#x\n", p2[i], &p2[i]);

         }

 

         //手动释放内存

         if (p != NULL){

                   free(p);

                   p = NULL;

         }       

         if (p2 != NULL){

                   free(p2);

                   p2 = NULL;

         }

 

         getchar();

}

1.3.4动态内存分配注意事项

1.不能多次释放

2.释放完之后(指针仍然存储有地址值),给指针置NULL,标志释放完成

3.内存泄露 

p重新赋值之后,再free,并没有真正释放内存,正确的做法是重新赋值前先free

//错误写法

void main(){

         //40M

         int* p1 = malloc(1024 * 1024 * 10 * sizeof(int));

         //80M

         p1 = malloc(1024 * 1024 * 10 * sizeof(int) * 2);

         free(p1);

         p1 = NULL;

         getchar();

}

//正确写法

void main(){

         //40M

         int* p1 = malloc(1024 * 1024 * 10 * sizeof(int));

         free(p1);//重新赋值前先释放

         p1 = NULL;

         printf("%#x\n",p1);

 

         //80M

         p1 = malloc(1024 * 1024 * 10 * sizeof(int) * 2);

         free(p1);

         p1 = NULL;

         getchar();

}

1.3.5字符串

字符串的几种表示方法

1)  使用字符数组表示字符串

char str[] = {'c','h','i','n','a','\0'};     //如果末尾没有’\0’,控制台会输出乱码

char str[6] = { 'c', 'h', 'i', 'n', 'a' };

注意: ’\0’表示结束符,不指定数组长度时需要末尾加上’\0’结束符;

指定字符数组长度且数组长度大于需要存储的字符个数,可以不加结束符;

还可以使用下面的表示方法:

char str3[] ="hahakkk";

2)  字符指针表示字符串

char *str = "how are you?";

两种表示方法有什么不同呢?

字符数组赋值只能在声明的时候赋值

字符数组表示字符串可以修改字符串,字符指针表示字符串不可以修改

 

字符串在线API网址:

http://www.kuqin.com/clib/string/strcpy.html

关于字符串与字符数组的区别请参考博客文章

http://blog.csdn.net/coderlei/article/details/79269038

 

函数名: stpcpy

用法:char *stpcpy(char *dest,char *src);

功能:把src所指由NULL结束的字符串复制到dest所指的数组中。

说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。

        返回指向dest结尾处字符(NULL)的指针。

举例:

#include <stdio.h>

#include <string.h>

int main(void)

{

   char string[10];

   char *str1 = "abcdefghi";

   stpcpy(string, str1);

   printf("%sn", string);

   return 0;

}

函数名: strcat

功  能: 字符串拼接函数

用  法: char*strcat(char *destin, char *source);

程序例:

#include <string.h>

#include <stdio.h>

int main(void)

{

   char destination[25];

   char *blank = " ", *c = "C++", *Borland = "Borland";

   strcpy(destination, Borland);

   strcat(destination, blank);

   strcat(destination, c);

   printf("%sn", destination);

   return 0;

}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值