簡體   English   中英

C ++ char *指針傳遞給函數並刪除

[英]C++ char * pointer passing to a function and deleting

我有以下代碼:

#include <iostream>
using namespace std;

void func(char * aString)
{
    char * tmpStr= new char[100];
    cin.getline(tmpStr,100);
    delete [] aString;
    aString = tmpStr;
}

int main()
{
    char * str= new char[100];
    cin.getline(str,100);
    cout<< str <<endl;
    func(str);
    cout<< str <<endl;
    return 0;
}

為什么第二個cout不打印第二個輸入字符串? 如何更改此代碼才能使用它?

正如GregS所說,簡單的答案是使用引用聲明你的函數:

void func(char *&aString)

然而,它並不是真正的最佳解決方案。 在C ++中,您通常避免使用簡單數組並使用容器。

#include <iostream>
#include <string>

void func(std::string &s)
{
    std::getline(std::cin, s);
}

int main()
{
    std::string str;
    func(str);
    std::cout << str << std::endl;
    return 0;
}

因為第二個cout將打印str指向的內容。 並且,主函數中的str ,在調用func之前和之后將具有相同的值。

實際上,在func函數中,您正在更改aString變量的值。 但這是主要的另一個變量而不是str

如果希望更改str的值,則必須通過引用或指針將其傳遞給func (注意你寫的是通過指針傳遞字符。我的意思是你必須通過指針傳遞指針: void func(char **str_ptr) ,或者通過引用void func(char *&str_ref)

如果你真的在做C ++,你應該使用std :: string而不是舊的C字符串。

通過指針傳遞指針的示例:

func(char ** aString)
{
    char * tmpStr= new char[100];
    cin.getline(tmpStr,100);
    delete [] *aString;
    *aString = tmpStr;
}

另外你應該這樣稱呼: func(&str);

當從main()調用func()時,str指針的值被傳遞給函數(這是通過它的值復制到堆棧來完成的)

調用func()時存儲在堆棧上的值成為func()中的局部變量aString。 您可以修改此值,但只要func()返回它的所有局部變量就會被丟棄。 aString的值不會被復制回str

要使代碼工作,您必須:

  • 使用aString指向的緩沖區來讀取數據:cin.getline( aString ,100); 要么
  • 將指針傳遞給指針:void func(char ** aString)

將func更改為

void func(char * aString)
{
    cin.getline(aString,100);
}

它起作用,至少它對我有用。

如果您的目標是實際從鍵盤讀取一行,請執行以下操作:

std::string foo;

std::getline(std::cin, foo);

否則,當您將指針傳遞給函數時,指針將按值傳遞 這意味着您無法在函數內更改指針本身,但您可以更改它指向的對象。 在C ++中,您可以按如下方式執行此操作:

void bar(std::string & s) {
    std::getline(std::cin, s);
}

// in calling code
    std::string foo;

    bar(foo);

這會將對字符串的引用傳遞給函數。 該函數現在可以更改字符串的內容。

如果要編寫一個分配一些內存來存儲結果的函數,請執行以下操作:

boost::shared_array<char> foo() {
    boost::shared_array<char> result(new char[100]);
    std::cin.getline(result.get(), 100);
    return result;
}

指針按值傳遞。 是的,您可以更改指針指向的內容 ,但退出函數時會保留舊地址本身。 因此,“aString = tmpStr”; 變得無用,“char * tmpStr = new char [100];” 造成內存泄漏。 您需要通過引用傳遞指針:

void func(char*& aString)
{
    char * tmpStr= new char[100];
    cin.getline(tmpStr,100);
    delete [] aString;
    aString = tmpStr;
}

賦值給函數中的參數aString對main()中的str沒有影響

你可能會試試

    return aString 

在主要的

    str = funct(str);

但事實上,沒有理由將str傳遞給函數。

aString = tmpStr只是將astring (即地址/指針)的值更改為另一個值(即另一個地址/指針),而不是aString指向的內容。

您可以嘗試將簽名更改為:

void func(char ** aString)

並將最后兩行func更改為:

delete [] *aString;
*aString = tmpStr;

因此,最后一行導致程序將存儲在aString指向的內存中的地址更改為新分配的地址( tmpStr )。 (我知道,這是令人難以置信的。)

然后通過它來調用它

func(&str);

您需要傳遞str作為參考。

#include <iostream>

void func(std::istream& is, std::string& aString)
{
    std::getline(is, aString);
}

int main()
{
    std::string str;
    std::getline(std::cin, str);
    if(std::cin)
        std::cout<< str << '\n';
    std::string str;
    func(std::cin, str);
    if(std::cin)
        std::cout<< str << '\n';
    return 0;
}

傳遞給func()的指針aString表示可以讀取和寫入字符串str位置(在哪個地址)。 當你說aString = tempStr ,你將用一個新值( tempStr指向的字符串的地址)替換它的原始值( str指向的字符串的地址)。 這不會導致str指向與tempStr相同的位置。

想象一下,我和朋友的家庭住址給你一張紙。 然后你把它刮掉並寫上你兄弟(住在倫敦)的地址。 如果我決定去拜訪我的朋友,我將不會發現自己前往倫敦,即使你可能有一張紙上寫着“保羅的朋友:123倫敦”。

要讓main打印出你在func ()中輸入的字符串,你可以將輸入字符串復制到aString(你將你的兄弟移動到我朋友家),或者將指針或引用傳遞給str(讓我給你我的地址)預訂,所以你可以把我的朋友的條目改為倫敦)。 無論哪種方式,下次我訪問“我朋友的家”時,你的兄弟都會在那里。

暫無
暫無

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

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