将char*转换为std::string的大小为1的读取无效

Invalid read of size 1 converting char* to std::string

本文关键字:小为 读取 无效 char string 转换 std      更新时间:2023-10-16

Mytest.cpp包含以下代码。我用valgrind描述了它,valgrind显示了错误。我错过了什么?

#include<string>
#include<cstring>
#include<iostream>
void TestString(std::string & str)
{
    char * tmpBuff = new char[3];
    tmpBuff[0] = 'f';
    tmpBuff[1] = 'o';
    tmpBuff[2] = 'o';
    str = tmpBuff;
    delete [] tmpBuff;
}
int main(int argc, char* argv[])
{
    std::string test_string;
    TestString(test_string);
    std::cout<<test_string;
    return 0;
}

valgrind log

==5026== Invalid read of size 1
==5026==    at 0x4A07F64: strlen (mc_replace_strmem.c:403)
==5026==    by 0x347E29E14B: std::string::operator=(char const*) (in /usr/lib64/libstdc++.so.6.0.13)
==5026==    by 0x4009AD: TestString(std::string&) (test.cpp:11)
==5026==    by 0x4009EC: main (test.cpp:18)
==5026==  Address 0x4c22043 is 0 bytes after a block of size 3 alloc'd
==5026==    at 0x4A07152: operator new[](unsigned long) (vg_replace_malloc.c:363)
==5026==    by 0x400979: TestString(std::string&) (test.cpp:7)
==5026==    by 0x4009EC: main (test.cpp:18)

tmpBuff缺少终止的

它应该包含4个字符:'f', 'o', 'o', ''

尝试以下修复

void TestString(std::string & str)
{
    char * tmpBuff = new char[4]; // <<<
    tmpBuff[0] = 'f';
    tmpBuff[1] = 'o';
    tmpBuff[2] = 'o';
    tmpBuff[3] = ''; // <<<
    str = tmpBuff;
    delete [] tmpBuff;
}

C样式字符串需要一个终止的字符。

您正在调用的std::string(const char*)构造函数需要一个以nul结尾的字符串。您没有传递一个,因此结果是未定义的行为。构造函数将尝试读取,直到找到为止。

所以,传递一个以nul结尾的字符串,一切都会好起来的。