【问题标题】:How to pass char* by value C++?如何通过值 C++ 传递 char*?
【发布时间】:2021-06-19 00:20:51
【问题描述】:

我已经定义了一个char* content 类型的属性,它接受一个字符串,该字符串甚至包含\0 这样的字符,这样我就不能使用string 类型。

当我尝试为内容定义设置器时,这里的问题是:

void MyClass::setContent(char* content)
{
    if(this->contentLength!=0){
        if(this->content)
            free(this->content);
        this->content = (char*)malloc(this->contentLength);
        memset(this->content,0,this->contentLength);
        memcpy(this->content,content,this->contentLength);
    }
}

知道contentLength也是MyClass的一个属性。

但是在另一个堆栈中,我定义了一个返回 MyClass 对象的函数:

MyClass myfunction(args) {
    MyClass myclass;
    /**
     *Do some stuff on myclass
     */
    return myclass;
}

在另一个堆栈上,我已经定义了这个:

MyClass element = myFunction(args);

这里我丢失了内容,因为它总是指向第一个堆栈中myclass 的地址。

如何将content 复制到新对象element

我正在处理C++98,无法实施c++11 上的任何解决方案。

【问题讨论】:

  • 如果你有一个 C++98 编译器,你可以编译(从它的源代码)一个最近的 GCC 编译器(例如 GCC 10 在 2021 年初,然后你有一个 C+ +14 编译器在您的计算机上(当然您可以使用std::string and the string library
  • @BasileStarynkevitch,我别无选择,只能使用 C++98。我在嵌入式环境中工作。
  • GCC 可以编译为嵌入式处理器的交叉编译器。参见例如CHARIOTthis draft report。更多信息,请给我发电子邮件(英文或法文)至basile@starynkevitch.net
  • @BasileStarynkevitch,问题是content 包含的字符和符号据我所知如果我使用\0 这样的字符串是不被接受的。
  • std::string 接受任何char,包括'\0'。 C++98 或现代 C++。但如果不是std::string,另一个比原始char* 更好的可行替代方案是std::vector<char>

标签: c++ arrays string reference char


【解决方案1】:

我定义了一个char* 内容类型的属性,它接受一个字符串,该字符串甚至包含\0 之类的字符,

你的问题就在那里。如果你传递了一个char *,更糟糕的是,使用它来管理由malloc() 返回的动态分配的内存,有很多事情可能会出错。

只需传递 std::vector<char> 即可。它跟踪自己的长度,不关心它包含多少'\0' 值,并且可以根据需要动态调整大小。例如,您可以重新实现

void MyClass::setContent(const std::vector<char> &content)
{
    this->content = content;    // this will copy all of the characters
                                //  from content to this-content
                                //  and manage memory for you
}

有很多关于std::vector 的文档,例如cppreference vector page,解释了vector 支持的操作。只要您不厌其烦地适当地使用它的操作(它不是免费的)std::vector&lt;char&gt; 将使您的生活更轻松。虽然在 C++ 标准之间有一些 std::vector 的演变,但即使是 C++98 版本也应该足以满足您的需求。

【讨论】:

    【解决方案2】:

    C++如何通过值传递char*?

    与其他类型通过值传递的方式相同:不要使用引用参数。示例:

    void function_name(char*); // the pointer will be passed by value
    

    如何将content 复制到新的对象元素中?

    这就是你所做的。您复制了指针,因此副本指向同一个数组。

    如果你想进行深拷贝,那么你可以分配一个新数组,将新指针指向这个单独的分配,然后从旧数组中复制字符串。

    但这不一定是您应该编写课程的方式。您应该做的是根据用例使用std::string 成员或std::vector&lt;char&gt;


    一个字符串甚至包含类似 \0 的字符,这样我就不能使用string 类型。

    不清楚你的意思是什么。如果你试图说std::string 不能包含空终止符,那你就错了。


    附:避免在 C++ 中使用malloc

    【讨论】:

      【解决方案3】:

      https://en.cppreference.com/w/cpp/language/copy_constructor 当您按值返回对象时,将调用复制构造函数来复制您的对象。

      如果您不手动创建一个,则会生成一个默认的复制构造函数。它只是复制指针,所以两个指针指向同一个数组。

      您可以像这样手动创建一个复制构造函数:

      MyClass(const MyClass& other)
      {
          this->contentLength = other.contentLength;
          this->content = (char*) malloc(this->contentLength);
          memcpy(this->content, other.content, this->contentLength);
      
          // Copy every other field manually here, if you have any.
      }
      

      更新: 请参阅 eerorika 和 Peter 的回答,了解更好的做法以及如何避免这种需要。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2020-04-01
        • 2018-09-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多