mark:蛋蛋的忧伤,android 源码,NDK、、、
1.c程序中内存的5大分区
栈:编译器编译时候动态分配与清除,如局部变量和形参,在使用的时候在栈中分配地址,结束时候回收 ;
堆:由new 分配 由delete 回收
自由区; 由malloc分配
全局/静态区:
常量区:
2.java
◆寄存器:我们在程序中无法控制
◆栈:存放基本类型的数据和对象的引用,但对象本身不存放在栈中,而是存放在堆中(new 出来的对象)
◆堆:存放用new产生的数据
◆静态域:存放在对象中用static定义的静态成员
◆常量池:存放常量
◆非RAM存储:硬盘等永久存储空间
int[] a = new int[10];//new 在堆中得到了分配的地址,a在栈中得到分配的地址,a为new 的引用对象
String s="Hello world";
String y ="Hello world"; //x==y true
先在栈中创建一个对String类的对象引用变量s,然后查找栈中有没有存放"Hello world",如果没有,则将"Hello world"存放进栈,并令s指向“Hello world”,如果已经有”Hello world” 则直接令s指向“Hello world”。
String s=new String("Hello World");
用new()来新建对象的,它会在存放于堆中。每调用一次就会创建一个新的对象
3.
/*
* Copyright (C) 2009 The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#include <jni.h>
#include <string.h>
#include <stdio.h>
#include <android/log.h>
#include <android/bitmap.h>
#include <termios.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <math.h>
#define LOG_TAG "ctest"
#define LOGI(...) __android_log_print(ANDROID_LOG_INFO,LOG_TAG,__VA_ARGS__)
#define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__)
typedef struct Student {
int no;
int sex;
int age;
} Student, *StudentNode;
typedef struct Test {
int *data[10];
} Test;
void printfStudent(Student *s) {
LOGI("s->no = %d s->sex = %d s->age = %d", s->no, s->sex, s->age);
}
//值传递
void initStudent1(Student s) {
s.no = 1001;
s.sex = 0;
s.age = 18;
printfStudent(&s);
}
//地址传递
void initStudent2(Student *s) {
s->no = 1002;
s->sex = 0;
s->age = 19;
printfStudent(s);
}
//指针函数
Student *initStudent3() {
Student s; //存在栈中,结束时候其内容会被清除,得到的只是个栈地址,
s.no = 1003;
s.sex = 0;
s.age = 20;
return &s;
}
//地址传递
Student *initStudent4() {
Student *s = (Student *) malloc(sizeof(Student)); //s也是栈中,但指向了堆中的地址,返回了堆的地址
s->no = 1004;
s->sex = 1;
s->age = 19;
return s;
}
//地址传递 指针的指针
void initStudent5(Student **s) {
*s = (Student *) malloc(sizeof(Student));
}
//参数引用传递 导致形参s成为实参的别名,函数内部对形参s的操作也就变成了对于实参的操作,这种操作节省了复制的麻烦过程 c++ 文件
//void initStudent6(StudentNode &s) {
// s = (Student *) malloc(sizeof(Student));
// s->no = 1006;
// s->sex = 1;
// s->age = 19;
// printfStudent(s);
//
//}
void xxxx() {
int x = 10;
int *sssss = &x;
int **s = &sssss;
LOGE("%x %x %x ", &x, &sssss, &s);
LOGE("%x %x %x ", x, sssss, s);
LOGE("%x %x %x %x", x, *sssss, *s, **s);
//s 为ssss的地址,*s为ssss所保存的地址即ssss所指向的地址
}
void arry() {
int a[2][3] = { { 0, 1, 2 }, { 3, 4, 5 } };
int (*p)[3]; //数组指针
p = a;
int i = 0;
for (; i < 2; i++) {
LOGE("%x %x %x ", (*p)[0], (*p)[1], (*p)[2]);
p++;
}
int *q[2]; //指针数组
for (i = 0; i < 2; i++) {
q[i] = a[i];
}
for (i = 0; i < 2; i++) {
LOGE("%x %x %x ", q[i][0], q[i][1], q[i][2]);
}
}
void Java_com_example_ctest_jni_JavaNative_onMain(JNIEnv* env, jobject thiz) {
LOGE("c program beging ");
LOGE("initStudent1 Student s");
Student s;
initStudent1(s);
printfStudent(&s);
LOGE("initStudent1 Student s end");
LOGE("initStudent2 Student *ss beging");
Student s1;
Student *ss = &s1; //若未赋值,编译可以通过,运行时候报错
initStudent2(ss);
Student *ss1; //
ss1 = (Student *) malloc(sizeof(Student)); //动态分配一个Student大的内存区域,且ss1指向该区域的首地址
initStudent2(ss);
free(ss1);
LOGE("initStudent2 Student *ss end");
LOGE("Student *initStudent3 beging");
Student *sss = initStudent3(); //
printfStudent(sss);
Student *ssss = initStudent4();
printfStudent(ssss);
Student *sssss;
initStudent5(&sssss);
sssss->no = 1005;
sssss->sex = 1;
sssss->age = 19;
printfStudent(sssss);
arry();
LOGE("c program end ");
}