First, let's look at a piece of code:
typedef WORD unsigned short;JNIEXPORT jobject XXX_getString(JNIEnv* env, jobject thiz, jint file,jobject head,jobject word,jint index){jobject jstr = NULL;int i = 0,j,len; WORD *buf; int adr = (*env)->GetIntField(env,word,wd_ExplainAddress); len = getWordStartAddress(file,index + 1,(*env)->GetIntField(env,head,dh_CodeAddressTable)) - adr; buf = (WORD*)malloc(len + 2); if(buf == NULL){ return NULL; } lseek(file,adr,SEEK_SET); read(file,buf,len); buf[len / 2 + 1] = 0; while(buf[i]){ if((buf[i] >= 0xF800) &&(buf[i] <= 0xF8FF) || (buf[i] >= 0xF700) &&(buf[i] <= 0xF70D)){ j = i; while(buf[j]){ buf[j] = buf[j + 1]; j++; } continue; } i++; } buf[i] = 0; jstr = (*env)->NewString(env,buf,i); free(buf); return jstr;}
There is a line of the above Code, which causes the "@ aborting: Invalid heap address in dlfree" error.
The error message indicates that the memory is faulty and the error occurs when the memory is free, that is, the above 33rd rows. But how can we make an error in "free"? unless there is an error in the memory of malloc, the "free" is the wrong address, or the memory of malloc is out of bounds. For a rough look, the Buf address has not changed, so the address is correct. Is it out of the border? So how did they cross the border?
The Buf pointer is of the Word type and is allocated (LEN + 2) bytes, indicating that there are at least two bytes, and then the Buf [Len/2 + 1] = 0, set the last word allocated to 0, so the while statements of the 20 and 23 rows will not cross the border. Where is it? You may say that Len is less than 0, because this Len is calculated, so it is logically excluded. Well, Len won't be less than 0, while the loop won't go out of bounds. How can this happen?
Take a closer look. If Len is an odd number, for example, 3, Buf = malloc (3 + 2), The Buf contains 5 bytes and 19th rows, buf [3/2 + 1] = Buf [2] = 0, because Buf is of the Word type, each element has 2 bytes,Buf [2] is the 5th and 6 bytes after the start of the Buf, because the allocated Buf only has 5 bytes, And now it needs to access 6th bytes, so it is out of bounds.
During the test, we found that the Len produced by row 9th is always an even number, and there is no odd number, but it is still the same error. Therefore, this is a memory alignment problem. There are many online materials on memory alignment. Here we post a website for your reference:
Memory alignment rules and functions
Sorry, the above section is actually incorrect. I don't know how many people have read this blog and misled everyone. I'm sorry! In fact, this is not an alignment problem, that is, the memory is out of bounds. The main cause is 11th rows. Here, we were applying for a continuous word (two bytes per element) space, the results apply for byte (1 byte for each element) space, because malloc is allocated by the number of bytes, although the length of 2 bytes is increased, the memory will surely be out of bounds later. The above Buf [2] should be 4th and 5 bytes after the start of the Buf, so it is not out of bounds. Use an even number instead, for example, Len = 4, Buf = malloc (4 + 2), Buf has 6 bytes, 19th rows, buf [4/2 + 1] = Buf [3] = 0, because Buf is of the Word type, and Buf [3] is the 6th and 7 bytes after the start of BUF, because the allocated Buf only has 6 bytes, And now it needs to access 7th bytes, it is out of bounds. It can be seen that pointer usage must be strictly cautious, have a solid C language foundation, and understand the layout of program data in the memory. Otherwise, a program error occurs if you are not careful about it, the system crashes!