2014-12-01 175 views
0

我對我的程序中的SEGFAULT很困惑。我正在嘗試實施scanf。所以我傳遞const char作爲第一個參數,而不是解析它的%條目,並使用變量參數來存儲值。
我對此很困惑。
我不是C++ C++編程方面的專家。但我瞭解內存分配和使用情況。 這是我的代碼片段。 我使用getline傳遞給它作爲大小char和0的NULL指針。根據手冊它應該自己malloc內存。
我認爲這是一些func分配內存的壞主意。但讓我們考慮一下。
由於此func具有malloc內存,所以我必須釋放它,但是當我嘗試這樣做時,我遇到了分段錯誤,但是如果我保留原樣,程序中沒有內存泄漏。我正在使用valgrind來檢查內存泄漏。有時會出現分段錯誤

或者,調用函數getline()之前,* lineptr可以包含 指針的malloc在大小(3)分配的緩衝器* n個字節。如果 緩衝區不足以容納該行,getline()會使用realloc(3)調整其大小 ,並根據需要更新* lineptr和* n。

這是我的代碼片段。

s = va_arg(argp, char *); 
       if (lengthIsSet) { 
        size_t newLen ; 
        size_t readLen; 
        char *strInput = NULL; 
        length = atoi(lengthStr.c_str()); 
        readLen = getline (&strInput,&newLen,inputSteam); 
        if (!strInput) { 
         break; 
        }     
        int sizeToCopy = (length<readLen)?length:readLen; 
        memcpy(s,strInput,sizeToCopy+1); 
        s[sizeToCopy] = '\0'; 
} 

我試圖初始化size_t newLen = 0;似乎工作知道,但我不認爲它會導致問題。請幫忙解決這個問題。我將非常感謝任何幫助和解釋。

編輯

請建議如何正確地讀取用戶輸入使用C++。沒有明確使用scanf,vscanf等。請幫忙,因爲我花了幾個小時處理這個問題。我發現只有這個功能才能從流中讀取用戶輸入。也許有任何使用C++函數的好方法。我不贊成C++和C,所以不知道很多功能。

編輯2

void scanfCustom(const char* input, FILE *inputSteam, va_list argp) { 
    const char *p; 
    int * i; 
    bool formFound = false; 
    std::string lengthStr(""); 
    int length; 
    bool lengthIsSet = false; 
    unsigned u; 
    char *s; 
    p = input; 
     for (; *p != '\0'; p++) { 
     if ((formFound) && (*p >= '0' && *p <= '9')) { 
       lengthStr+=(*p); 
       lengthIsSet = true; 
       continue; 
      } 
     if (*p == '%') { 
      formFound = true; 
      continue; 
     } 
     formFound = false; 
     switch (*p) { 
      case 's': 
       s = va_arg(argp, char *); 
       if (lengthIsSet) { 
        size_t newLen = 0; 
        size_t readLen; 
        char *strInput = NULL; 
        length = atoi(lengthStr.c_str()); 
        readLen = getline (&strInput,&newLen,inputSteam); 
        if (!strInput) { 
         break; 
        }     
        int sizeToCopy = (length<readLen)?length:readLen; 
        memcpy(s,strInput,sizeToCopy+1); 
        s[sizeToCopy] = '\0'; 
        // free(strInput); 
        //fgets(s,length,inputSteam); 
       } 
//TODO READ FULL STR 
     } 
    } 
} 
+1

從代碼片段中很難判斷緩衝區的大小是否足夠容納sizeToCopy + 1個字節。 memcpy將無條件地將很多字節寫入緩衝區。如果's'太小,你可能會得到一個SEGFAULT。甚至不清楚's'是否是一個有效的內存指針。 – lurker 2014-12-01 17:55:43

+1

您可以使用'std :: string'而不是C-style字符串來減少SEGFAULT的出現次數。 – 2014-12-01 17:58:10

+0

您可以通過自己管理字符串來提高速度和效率。所以它值得知道如何使用字符串。 – 2014-12-01 17:59:51

回答

0

如果函數getline失敗(例如輸入流是無效或用戶確實CTRL-C沒有任何輸入)會發生什麼?

getline將返回-1,您將崩潰。