3

我已经执行了下面的代码,它工作得很好。由于它是关于指针的,我只是想确定一下。虽然我确信将 char* 分配给 string 会生成一个副本,即使我删除了 char*,string var 也会保留该值。

    #include <stdio.h>
    #include <string.h>
    #include <string>
    #include <iostream>

    int main()
    {
        std::string testStr = "whats up ...";
        int strlen = testStr.length();
        char* newCharP = new char[strlen+1];
        memset(newCharP,'\0',strlen+1);
        memcpy(newCharP,testStr.c_str(),strlen);


        std::cout << "  :11111111   :   " << newCharP << "\n";
        std::string newStr = newCharP ;

        std::cout << "  2222222 : " << newStr << "\n";
        delete[] newCharP;
        newCharP = NULL;

        std::cout << "  3333333 : " << newStr << "\n";
    }

我只是在我的公司项目中更改了一些代码,并且 char* 在 C++ 中的函数之间传递。char* 指针已复制到字符串,但 char* 在函数末尾被删除。我找不到任何具体的原因。所以我只是删除 char*,只要它被复制到一个字符串中。这会有什么问题吗...?

PS:我已经在 Codereview 中问过这个问题,但我得到了将其移至 SO 的建议。因此,我已将其标记为关闭并在此处发布问题。

4

3 回答 3

10

不,因为std::string复制了你的内容char*,所以当你不再需要它时,你可以随意删除它。

于 2013-03-10T13:24:41.027 回答
6

没有问题,只要newChar指向一个以null结尾的字符串,并且本身不为null。

std::string具有允许从 a 进行隐式构造的构造函数const char*。它会复制由输入表示的字符串,const char *因此它在假设char*是一个空终止字符串的情况下工作,因为没有其他方法可以知道要复制多少个字符到字符串自己的数据存储中。此外,NULL标准实际上不允许使用指针。

于 2013-03-10T13:25:26.320 回答
1

代码很好,如果您查看这里的构造函数,std::basic_string 将能够推断出std::string这里有两个有趣的构造函数:

(4) string(char const*,
           size_type count,
           Allocator const& alloc = Allocator() );

(5) string(char const* s,
           Allocator const& alloc = Allocator() );

两者都执行复制,第一个读取完全count字符,而第二个读取直到遇到 NUL 字符。


话虽如此,我积极鼓励您不要在这里使用动态分配。如果您想使用临时缓冲区,请考虑std::vector改用。

#include <stdio.h>
#include <string.h>
#include <string>
#include <iostream>

int main()
{
    std::string testStr = "whats up ...";
    unsigned strlen = testStr.length();

    std::vector<char> buffer(strlen+1);

    memset(&buffer[0],'\0',strlen+1);
    memcpy(&buffer[0], testStr.c_str(), strlen);

    std::cout << "  :11111111   :   " << &buffer[0] << "\n";

    std::string newStr(&buffer[0]);

    std::cout << "  2222222 : " << newStr << "\n";

    buffer.clear();

    std::cout << "  3333333 : " << newStr << "\n";
}

注意:vectorstring都有范围构造函数,从一系列迭代器中构建它们,我故意避免使用它们以避免混淆和你不知所措。只知道您可以使用它们来避免调用memcpy和冒缓冲区溢出的风险。

于 2013-03-10T14:09:07.237 回答