将 char* 赋值给字符串变量后删除它

4

我已经执行了下面的代码,它完美地运行了。由于它涉及指针,我想确认一下。虽然我确定将char*分配给字符串会复制值,即使我删除char*,字符串变量也会保留该值。

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

我正在更改公司项目中的一些代码,在C++中函数之间传递char*指针。char*指针已被复制到字符串中,但是在函数结束时删除了char*。我找不到任何具体原因。因此,我在将其复制到字符串中后就将char*删除了。这会有什么问题吗...?
附注:我已经在Codereview中问过这个问题,但是得到了将其移至SO的建议。因此,我在那里标记了这个问题并在此发布了问题。
3个回答

11
不行,因为std::string会复制您的char*内容,所以当您不再需要它时可以安全删除它。

7
只要newChar指向以null结尾的字符串且不为null本身,那么就没有问题。 std::string有一个构造函数,可以从const char*进行隐式构造。它会复制输入const char *所表示的字符字符串,因此假定char*是以null结尾的字符串,因为没有其他方法可以知道要将多少个字符复制到字符串自己的数据存储中。此外,按照标准规定,NULL指针实际上是不允许的。

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-character)为止。


说了这么多,我强烈建议您不要在这里使用动态分配。如果您想要一个临时缓冲区进行操作,请考虑使用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";
}

注意:无论是 vector 还是 string 都有范围构造函数,可以从迭代器的范围构建它们。我故意避免使用它们以避免混淆和过度负担。只要知道你可以使用它们来避免调用 memcpy 并避免缓冲区溢出。

谢谢Matt,实际上char是从另一个函数传递过来的。就像我说的,我正在处理一些旧代码,不能在所有函数调用中更改参数。我们的代码库非常大。这些char的删除在函数的许多部分执行,每个条件只执行一次。虽然我不喜欢代码重复,但我已经将char简单地复制到字符串中,并在函数开头删除了char - Manikandaraj Srinivasan
1
@ManikandarajS:嗯!我知道你的痛苦,我自己也不得不处理一些阴暗的应用程序:(在这种情况下,你正朝着正确的方向努力,试图限制“感染”,并调整你已有的代码,使其变得更好! - Matthieu M.

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接