簡體   English   中英

使用流提取到char指針時出現分段錯誤

[英]Segmentation fault when using stream extraction into a char pointer

我有個問題。 我有以下struct

typedef struct{
    int vin;
    char* make;
    char* model;
    int year;
    double fee;
}car;

然后我有以下方法詢問用戶制作汽車並將其作為char指針返回:

char* askMake(){
    char* tempMake = NULL;
    cout << "Enter Make:" << endl;
    cin >> tempMake;
    return tempMake;
}

然后我有一個臨時汽車struct

car tempCar;

我試圖以這種方式為它分配一個值:

tempCar.make = askMake();

它編譯得很好,但是我在運行時遇到了分段錯誤。

你沒有為tempMake指定任何內存指向。 當您讀入數據時,它會將其讀入tempMake恰好指向的任何隨機位置。

擺脫指針並使用std::string代替使生活更簡單。

你必須為tempMake分配內存。

試試這個:

char* askMake(){
    char* tempMake = new char[1024]; //Arbitrary size
    cout << "Enter Make:" << endl;
    cin >> tempMake;
    return tempMake;
}

不要忘記使用delete[]釋放您分配的內存。

如果您不希望內存泄漏,可以使用boost :: shared_ptr或boost :: scoped_ptr等智能指針來避免這種情況。 你可以在這里看到更多相關信息。

你真的想在這里使用std :: string而不是char *。 問題是您正在嘗試將用戶輸入讀入尚未分配的內存(tempMake)。

std::string askMake(){
    std::string tempMake;
    cout << "Enter Make:" << endl;
    cin >> tempMake;
    return tempMake;
}

你也可能想在你的'car'結構中使用std :: string而不是char *。

你得到一個段錯誤,因為你正在寫一個空指針。 您應該為cin創建一個新的內存空間來寫入,然后在它返回時復制它。 std::string可以為你做到這一點:

std::string askMake() {
    std::string temp;
    cout << "Enter Make:" << endl;
    cin >> temp;
    return temp;
}

其他人告訴你需要做些什么來解決當前問題:使用new或malloc為tempMake分配空間,或者使用std:string。

您可能不希望從函數返回指向結構成員的指針。 雖然您可以在執行此操作時制作正確的代碼,但也有很好的理由這樣做,這可能不是其中一個實例。 問題與所有權有關。 如果你通過指針公開變量,那么最終用戶可以自由地將那個人傳遞給其他函數,這些函數可能最終在你想要之前釋放它,或者以其他方式改變它。 另外,當你決定自己釋放內存時會發生什么? 如果您的團隊中不知道您的代碼的人在您刪除它后使用該指針值該怎么辦? 如果沒有人釋放它並且你一遍又一遍地使用這個結構怎么辦? 這是內存泄漏。

最好的模型是隱藏此功能是為了不允許直接訪問您的類成員,除非絕對必要,否則不要從函數返回指針。 在C ++中,我認為最優雅的解決方案是返回一個std :: string。 在直接C中,將char **(我們稱之為x)傳遞給函數,並執行以下操作:

int askMake(char** x)
{
    char tempMake[100];//or some value you know to be large enough
    cout << "Enter Make:" << endl;
    cin >> tempMake;//i would use cin.get() so you know the length of the string.
    //so let's pretend we have that length in a variable called stringLen.

    *x = new char[stringLen];
    for(int i = 0; x && i < stringLen; i++)
    {
        (*x)[i] = tempMake[i];
    }

    if(x)
       return 0;
    else
       return 1;
}

正如其他人所說,你通過使用char*代替std::string給自己額外的工作。 如果切換到std::string ,它將如下所示:

#include <string>
struct car
{
  int vin;
  std::string make;
  std::string model;
  int year; 
  double fee; 
}; 

std::string askMake()
{
  std::string make;
  cout << "Enter Make:" << endl;
  cin >> make;
  return make;
}

int main()
{
  car tempCar;
  tempCar.make = askMake();
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM