C ++ char *指针传递给函数并删除

时间:2010-07-01 12:23:14

标签: c++ pointers

我有以下代码:

#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不打印第二个输入字符串?如何更改此代码才能使用它?

11 个答案:

答案 0 :(得分:12)

正如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;
}

答案 1 :(得分:6)

因为第二个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);

答案 2 :(得分:2)

当从main()调用func()时,str指针的值被传递给函数(这是通过它的值复制到堆栈来完成的)

调用func()时存储在堆栈上的值成为func()中的局部变量aString。您可以修改此值,但只要func()返回它的所有局部变量就会被丢弃。 aString 的值不会被复制回str

要使您的代码正常工作,您必须:

  • 使用aString指向的缓冲区读取数据:cin.getline( aString ,100); 或
  • 将指针传递给指针:void func(char ** aString)

答案 3 :(得分:2)

将func更改为

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

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

答案 4 :(得分:1)

如果您的目标是从键盘上实际读取一行,请执行以下操作:

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;
}

答案 5 :(得分:1)

指针按值传递。是的,您可以更改指针所指向的内容,但退出该函数时会保留旧地址本身。因此,“aString = tmpStr”;变得无用,“char * tmpStr = new char [100];”造成内存泄漏。您需要通过引用传递指针:

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

答案 6 :(得分:0)

赋值函数中的参数aString对main()

中的str没有影响 你可以尝试

    return aString 

并在主

    str = funct(str);

但事实上,没有理由将str传递给函数。

答案 7 :(得分:0)

aString = tmpStr只是将astring(即地址/指针)的值更改为另一个值(即另一个地址/指针),但不是{{1}指向的内容。 1}}。

您可以尝试将签名更改为:

aString

void func(char ** aString) 的最后两行更改为:

func

因此,最后一行会导致程序将delete [] *aString; *aString = tmpStr; 指向的内存中存储的地址更改为新分配的地址(aString)。 (我知道,这令人难以置信。)

然后通过

调用它
tmpStr

答案 8 :(得分:0)

您需要传递str作为参考。

答案 9 :(得分:0)

#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;
}

答案 10 :(得分:0)

传递给func()的指针aString表示您可以读取和写入字符串str的位置(在哪个地址)。然后当你说aString = tempStr时,你用一个新值(str指向的字符串的地址替换它的原始值(tempStr指向的字符串的地址) )。这不会导致str指向与tempStr相同的位置。

想象一下,我和朋友的家庭住址给你一张纸。然后你把它刮掉并写上你兄弟(住在伦敦)的地址。如果我决定去拜访我的朋友,我将不会前往伦敦,即使你可能有一张纸上写着“保罗的朋友:123伦敦”。

要让main打印出您在func()中输入的字符串,您可以将输入字符串复制到aString(将您的兄弟移动到我朋友的家中),或者传递指针或引用str(让我给你我的地址簿,这样你就可以把我朋友的条目改为伦敦)。无论哪种方式,下次我访问“我朋友的家”时,你的兄弟都会在那里。