将char *分配给字符串变量后删除它

时间:2013-03-10 13:22:38

标签: c++ string pointers char

我已经执行了以下代码,它完美无缺。因为它是指针,我只想确定。虽然我确信将字符串赋值给字符串会产生副本,即使我删除了char *,字符串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 *,只要它被复制到一个字符串中。这会有什么问题......?

P.S:我已经在Codereview中提出了这个问题,但我建议将其移至SO。所以我已将其标记为关闭并在此处发布问题。

3 个答案:

答案 0 :(得分:9)

不,因为std::string会复制char*的内容,因此您可以在不再需要时将其删除。

答案 1 :(得分:5)

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

std::string具有允许const char*隐式构造的构造函数。它创建了由输入const char *表示的字符串的副本,因此它假设char*是一个以空字符结尾的字符串,因为没有其他方法可以知道要复制到多少个字符字符串自己的数据存储。此外,标准实际上不允许NULL指针。

答案 2 :(得分:1)

代码很好,如果你看一下std::basic_string here的构造函数,你就可以推断出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并冒着缓冲区溢出的风险。