2015-09-27 37 views
0

我寫我自己的getline功能K後跟& R C書使用c中的指針覆蓋內存的可能性?

void getline(char * const str) 
{ 
    int c; 
    char* temp = str; 
    while ((c=getchar()) != '\n') { 
    *temp = c; 
    temp++; 
    } 
    *temp = '\0' 
} 

而且它用來初始化字符串

char *str1, *str2; 
printf("Type string 1: "); 
getline(str1); 
printf("Type string 2: "); 
getline(str2); 

只是想知道的是,如果存儲位置str1str1點是非常接近,然後getline(str2)覆蓋字符串1中的內容?

這是可能的我怎麼能避免它?謝謝!

更新:

是程序停止執行上面的代碼片斷,但下面的代碼工作:

#include <stdio.h> 
main() 
{ 
    char* str; 
    char* temp = str; 
    int c; 
    while ((c=getchar()) != '\n') { 
    *temp = c; 
    ++temp; 
    } 
    *temp = '\0'; 
    printf("%s\n", str); 
} 

這裏str也未初始化字符指針,但爲什麼deoesn't它給我一個錯誤?

+0

這是行不通的? – ameyCU

+0

'char * str1,* str2;'未初始化。所以改爲'char str1 [128],str2 [128];' – BLUEPIXY

回答

3

你有什麼是Undefined Behavior

說明:

你定義了兩個指針char

char *str1, *str2; 

但你沒有初始化他們。他們指向一些「隨機」內存位置,因爲它們未初始化。

然後,通過str1str2getline這裏:

char* temp = str; 

temp點到str點。然後,在循環中,

*temp = c; 

您寫入此內存位置。這會寫入無效的內存位置。並調用UB

修復:

  1. 您可以使用自動陣列與一個固定大小:

    char str1[101], str2[101]; 
    

    請注意,您應在getline功能打破了循環時,在循環中添加一個檢查用戶輸入了100個字符,因此不會有buffer overflow

  2. 更好的解決方案是使用動態內存分配。您需要使用mallocrealloc。這些功能需要stdlib.h標題。

    固定碼(未經測試)

    char* getline() 
    { 
        char* str; 
        int c, size = 10, counter = 0; 
    
        str = malloc(size); /* Allocate `size` memory */ 
    
        if(str == NULL) 
        { 
        printf("malloc failed to allocate memory"); 
        exit(-1); /* Exit the program */ 
        /* Or 
        return NULL; 
        */ 
        } 
    
        while ((c = getchar()) != '\n' && c != EOF) { /* Added check for EOF as well */ 
        str[counter] = c; 
        counter++; 
    
        if(counter == size) 
        { 
         char* temp = str; /* Backup in case realloc fails */ 
         size += 10; /* Which is the same as `size = size + 10` */ 
         str = realloc(str, size); /* realloc size(20) memory */ 
    
         if(str == NULL) /* If realloc failed */ 
         { 
         printf("reallocing memory failed"); 
         str = temp; /* str is NULL, retrieve the original contents */ 
         break; /* Break out of the loop */ 
         } 
        } 
        } 
    
        str = realloc(str, counter + 1); /* realloc `counter + 1` memory */ 
    
        str[counter] = '\0'; 
        return str; 
    } 
    

    和調用函數,

    char* str1 = getline(); 
    if(str1) 
        puts(str1); 
    free(str1); 
    
    
    char* str2 = getline(); 
    if(str2) 
        puts(str2); 
    free(str2); 
    
+0

非常感謝!你能看看我的更新問題嗎? –

+0

@SouthParker未定義的行爲(UB),意味着任何事情都可能是結果。它可能按預期工作。當你添加一個簡單的'printf'時,它可能會停止工作。它可能會崩潰。它可能會出現分段錯誤。它可能會做別的等等等 –

+0

乾杯!非常感激 :) –

0

str1str2不因此初始化它會被不確定的行爲。你可以訪問不允許的內存,這會導致程序崩潰。

您必須爲每個指針分配足夠的內存並傳遞其大小以獲取行函數,以確保您只在分配的內存中進行寫入。

0

str1str2是uninitialized.Right現在你寫(*temp = c;)爲無效(或授權)內存位置調用UB

首先您需要分配內存給str1str2

str1=malloc(100);  // check return 
str2=malloc(100); 

能夠寫入該內存位置。

只是想知道,如果內存位置str1和str1指向非常接近,然後getline(str2)覆蓋字符串1中的內容呢?這是可能的我怎麼能避免它?

而至於你的關注,由這些malloc分配不重疊(將兩個不同的傳染性內存塊)的內存,因此,如果您還傾向於寫超出這些內存位置,你會調用未定義行爲,如果你是幸運分段錯誤)。因此,恕我直言,將不會有任何0123'覆蓋str1的情況。