标签:释放 类型 ssl android native ++ 越界 c++ efi
我们实现下面的一个功能:
1、首先在java层传递一个字符串到c层,c层首先将jstring转换成char*类型,然后将两个字符串相加,然后再再将char*类型转换成jstring,在上层显示出来
我们来看底层程序的代码:
// // Created by wei.yuan on 2017/6/13. // #include <jni.h> #include <string.h> #include <pthread.h> #include "im_weiyuan_com_jni_Sdk.h" #include "im_weiyuan_com_jni_Sdk_OnSubProgressListener.h" #include "im_weiyuan_com_jni_Sdk_SdkHodler.h" JavaVM *g_VM; jobject g_obj; #include <jni.h> #include <string.h> #include <time.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <dlfcn.h> #include <assert.h> #include <android\log.h> #include <errno.h> #include <pthread.h> #include <android/log.h> #define LOG_TAG "Native" #define LOGE(...) __android_log_print(ANDROID_LOG_ERROR,LOG_TAG,__VA_ARGS__) /*方法三,调用C库函数,*/ char* join(char *s1, char *s2) { char *result = malloc(strlen(s1)+strlen(s2)+1);//+1 for the zero-terminator //in real code you would check for errors in malloc here if (result == NULL) exit (1); strcpy(result, s1); strcat(result, s2); return result; } /*1、第一步将输入的jstring类型转换成char*类型 * 2、将两个char*类型的字符串拼接起来 * 3、将cha*类型的转换成jstring类型,返回给java层 * * * * */ JNIEXPORT jstring JNICALL Java_im_weiyuan_com_jni_Sdk_getStringFromC (JNIEnv * env, jobject jobj, jstring jstr){ const jbyte *str; str = (*env)->GetStringUTFChars(env, jstr, NULL); if (str == NULL) { return NULL; /* OutOfMemoryError already thrown */ } LOGE("123456789:%s\n",str); char *hello = "I from C++"; char*result = NULL; result = join(str,hello); LOGE("123456789 result len is :%d\n",strlen(result)); (*env)->ReleaseStringUTFChars(env, jstr, str); //malloc申请的内存记得要是否 if(result !=NULL){ LOGE("123456789 result len is free\n"); free(result); } return (*env)->NewStringUTF(env, result); }
这里一定要注意strcat和strcpy的使用方式:
上面的代码还有一个致命的问题:
要为所需的内存分配足够的空间,否则会出现严重的错误。同时,分配的时候若想使用strlen()来确定内存大小时,要注意进行转换,因为内存中是以字节数来计算大小的,而strlen返回的只是字符串长度,如strlen("abc")返回的3,但是可能每个字符占两字节(不同系统有所不同),即内存大小应该为6。
所以上面的代码应该写成下面的形式:
/*方法三,调用C库函数,*/ char* join(char *s1, char *s2) { char *result = malloc((strlen(s1)+strlen(s2)+1)* sizeof(char));//+1 for the zero-terminator //in real code you would check for errors in malloc here if (result == NULL) exit (1); strcpy(result, s1); strcat(result, s2); return result; }
头文件:#include <string.h> strcat() 函数用来连接字符串,其原型为: char *strcat(char *dest, const char *src); 【参数】dest 为目的字符串指针,src 为源字符串指针。 strcat() 会将参数 src 字符串复制到参数 dest 所指的字符串尾部;dest 最后的结束字符 NULL 会被覆盖掉,并在连接后的字符串的尾部再增加一个 NULL。 注意:dest 与 src 所指的内存空间不能重叠,且 dest 要有足够的空间来容纳要复制的字符串。 【返回值】返回dest 字符串起始地址。 【实例】连接字符串并输出。
#include <stdio.h> #include <string.h> int main () { char str[80]; strcpy (str,"these "); strcat (str,"strings "); strcat (str,"are "); strcat (str,"concatenated."); puts (str); return 0; }
错误案例一:
在实际开放中,我们可能会用到strcat拼接两个字符串,例如 char a[6] = "hello"; char b[6] = "world"; strcat(a,b); free(a); free(b); 此时会出现越界情况,由于a只有6个字符的空间,拼接后超出了本身空间大小,因此会报错, 所以需要用realloc重新给a分配足够的空间来存储新的字符串。 在使用指针时,需要时刻注意空间的分配,空间的大小,空间的释放等问题
标签:释放 类型 ssl android native ++ 越界 c++ efi
原文地址:http://www.cnblogs.com/kebibuluan/p/7066296.html