2012-06-25 49 views
2

我的代碼,發現了以下錯誤:免費():無效的下一個大小(快)字符串太長?

free(): invalid next size (fast) 

我的代碼:

#include <stdio.h> 
    #include <string.h> 
    #include <stdlib.h> 


    int main() 
    { 
char *temp_str; 
char *pos, *pos2; 
char *key = (char*)malloc(20); 
char *data = (char*)malloc(20); 
const char newline = '\n'; 

char *unparsed_data = "NEW_DATA_PACKET\n\ 
    Data Set 16-byte Universal Key\n\ 
    Unix Time Stamp (microsecs): 1319639501097446\n\ 
    Frame Number: 0\n\ 
    Version: 3\n\ 
    Platform Yaw Angle (deg): 15.22428\n\ 
    Platform Pitch Angle (deg): 1.78528\n\ 
    Platform Roll Angle (deg): 2.004111\n\ 
    Image Source Source: test\n\ 
    Image Coordinate System: Testing XXXXX\n\ 
    Sample Latitude (deg): 17.306791\n\ 
    Sample Longitude (deg): -60.26209\n\ 
    Sample True Altitude (m): 7.623407\n\ 
    Sample Horizontal FoV (deg): 0.1821277\n\ 
    Sample Vertical FoV (deg): 15.1879\n\ 
    Sample Rel. Azimuth Angle (deg): 291.70295\n\ 
    Sample Rel. Elevation Angle (deg): -5.941163\n\ 
    Sample Rel. Roll Angle (deg): 3.10959\n\ 
    Checksum: 4659\n"; 

temp_str = (char*)malloc(strlen(unparsed_data)); 

printf("\nThe original string is: \n%s\n",unparsed_data); 

//Ignore the first two lines 
pos = strchr(unparsed_data, newline); 
strcpy(temp_str, pos+1); 
pos = strchr(temp_str, newline); 
strcpy(temp_str, pos+1); 
printf("STARTING THE PARSER\n\n"); 
while(strlen(temp_str) > 2) 
{ 
    printf("\tstarting loop\n"); 
    //Getting the position of the colon and newline character 
    pos = strchr(temp_str, ':'); // ':' divides the name from the value 
    pos2 = strchr(temp_str, '\n'); //end of the line 
    realloc(key, (pos-temp_str-1)); //allocate enough memory 
    realloc(data, (pos2-pos)-1); 

    printf("After realloc \n"); 

    //copying into key and data 
    strncpy(key, temp_str, (pos-temp_str)); 
    strncpy(data, pos + 2, (pos2-pos)-2); 

    //Append null terminator 
    strcpy(key+(pos-temp_str-1)+1, ""); 
    strcpy(data+(pos2-pos)-2, ""); 


    printf("%s = ",key); 
    printf("%s\n",data); 

    assign_value(key,data, &gvals); 

    printf("The value has been assigned\n"); 
    strcpy(temp_str, pos2+1); 

    printf("Freeing key and data\n\n"); 

    free(key); 
    free(data); 

} 

return 0; 
    } 

我也越來越當打印

STARTING THE PARSER 

    starting loop 
After realloc 
Unix Time Stamp (m13196395 = 13196395 
The value has been assigned 
Freeing key and data 

*** glibc detected *** ./memory_alloc: free(): invalid next size (fast): 0x098cd008 *** 

最後一些垃圾,當我減少該字符串的長度,代碼完美工作。它正常工作與以下字符串:

char *unparsed_data = "NEW_DATA_PACKET\n\ 
    Data Set 16-byte Universal Key\n\ 
    Time Stamp: 1319639501097446\n\ 
    Frame Number: 0\n\ 
    Version: 3\n\ 
    Yaw Angle: 15.22428\n\ 
    Pitch Angle: 0.78528\n\ 
    Roll Angle: 2.004111\n\ 
    Source: test\n\ 
    Coor System: Test XXXXX\n\ 
    Latitude: 27.306791\n\ 
    Longitude: -60.26209\n\ 
    True Altitude: 7.623407\n\ 
    Hor FoV: 0.1821277\n\ 
    Ver FoV: 15.1879\n\ 
    Azimuth: 291.702954\n\ 
    Elevation: -0.433563\n\ 
    Roll: 0.79659\n\ 
    Checksum: 2659\n"; 

** * 解決方案: * **

int main() 
     { 
    char *temp_str; 
    char *pos, *pos2; 
    char *key = (char*)malloc(20); 
    char *data = (char*)malloc(20); 
    const char newline = '\n'; 

    char *unparsed_data = "NEW_DATA_PACKET\n\ 
The UAS Datalink Local Data Set 16-byte Universal Key\n\ 
Time Stamp: 1319639501097446\n\ 
Frame Number: 0\n\ 
Version: 3\n\ 
Yaw Angle: 15.22428\n\ 
Pitch Angle: 0.78528\n\ 
Roll Angle: 2.004111\n\ 
Source: test\n\ 
Coor System: Test XXXXX\n\ 
Latitude: 27.306791\n\ 
Longitude: -60.26209\n\ 
True Altitude: 7.623407\n\ 
Hor FoV: 0.1821277\n\ 
Ver FoV: 15.1879\n\ 
Azimuth: 291.702954\n\ 
Elevation: -0.433563\n\ 
Roll: 0.79659\n\ 
Checksum: 2659\n"; 


    temp_str = (char*)malloc(strlen(unparsed_data)); 

    //Ignore the first two lines 
    pos = strchr(unparsed_data, newline); 
    strcpy(temp_str, pos+1); 
    pos = strchr(temp_str, newline); 
    strcpy(temp_str, pos+1); 
    printf("STARTING THE PARSER\n\n"); 
    while(strlen(temp_str) > 2) 
    { 
     printf("\tstarting loop\n"); 
     //Getting the position of the colon and newline character 
     pos = strchr(temp_str, ':'); // ':' divides the name from the value 
     pos2 = strchr(temp_str, '\n'); //end of the line 
     char *new_key = (char*)realloc(key, (pos-temp_str+1)); //allocate enough memory 
     char *new_data = (char*)realloc(data, (pos2-pos+1)); 


     if(new_key) 
     key = new_key; 
     if(new_data) 
     data = new_data; 

     printf("After realloc \n"); 

     //copying into key and data 
     strncpy(key, temp_str, (pos-temp_str)); 
     strncpy(data, pos + 2, (pos2-pos)-2); 

     //Append null terminator 
     memset(key + (pos-temp_str) , '\0', 1); 
     memset(data + (pos2 - pos), '\0', 1); 


     printf("%s = ",key); 
     printf("%s\n",data); 

     assign_value(key,data, &gvals); 

     printf("The value has been assigned\n"); 
     strcpy(temp_str, pos2+1); 

     printf("Freeing key and data\n\n"); 

     free(key); key= NULL; 
     free(data); data = NULL; 

    } 

    return 0; 
     } 

回答

4

這裏是錯誤:

realloc(key, (pos-temp_str-1)); //allocate enough memory 
realloc(data, (pos2-pos)-1); 

realloc()返回新緩衝區(可能是不同的)的地址,與已在可能被釋放傳遞的緩衝區。舊的緩衝區然後傳遞到free(),但它們可能已經被釋放。你需要從realloc()保存返回值:

char* new_key = realloc(key, ...); /* Don't assign key = realloc(key, ...); 
             Since if realloc() fails it returns 
             NULL, but leaves the original 
             buffer unmodified. This will 
             result in a memory leak. */ 
if (new_key) 
{ 
    key = new_key; 
} 

free(key); 
key = NULL; /* Be sure assign key to NULL, otherwise dangling pointer will 
       be passed to realloc() on next iteration. */ 

而且,看到Do I cast the result of malloc?

+0

太棒了!它的工作,謝謝。我還使用了@wallyk解決方案的一部分,並使用memset來追加空終止符。 –

+0

我也讀過關於鑄造realloc,但我得到'無效轉換'從'void *'到'char *'[-fpermissive]' –

1

有這個代碼微妙的問題:

realloc(key, (pos-temp_str-1)); //allocate enough memory 
realloc(data, (pos2-pos)-1); 

    ... 
strncpy(key, temp_str, (pos-temp_str)); 
strncpy(data, pos + 2, (pos2-pos)-2); 

的重新分配的長度是n-1,但它將n個字符複製到它。這將是更好的:

key = realloc(key, pos - temp_str + 1); 
memset (key, 0, pos - temp_str + 1); // make sure terminating NUL present 

data = realloc(data, pos2 - pos + 1); 
memset (data, 0, pos2 - pos + 1); 
    ... 
strncpy(key, temp_str, pos - temp_str); 
strncpy(data, pos + 2, pos2 - pos - 2); 
+0

嗯,你錯過了更大的問題。 OP正在拋棄'realloc'的返回值。 –

+0

@realloc:謝謝,我添加了它。 – wallyk

+0

另外,請注意,如果源的第一個「n」字符中沒有NULL,則'strncpy()'不會終止目標。 – twalberg

相關問題