The method of copying a string and a trap

Foreword

In the actual project development, string copy is a very common usage. There are many ways, we use, any problems generally do not occur, or is generally the compiler does not compile error, or even run error. However, some potential pitfalls are often present, such as when using VS 2017 development, you will find a lot of grammar compiler detected will be more rigorous, previously not being given such vs2010, vs2017 will not compile, or compile successful, run error.

Nonsense: just in time to work, I feel as long as the function can be achieved, is to complete the task. With experience, a lot of things you like to go to get to the bottom, to think, why so used, so with what benefits, efficiency will not be higher, the performance will not be better.

Well, nonsense is more than just words, following the official opening of today's discussion topic.

Copy format

There are many string copy the way, here I mainly talk about memcpy, strcpy, string :: copy of these three.

Memory copy memcpy

Function prototype

    void* __cdecl memcpy(
    _Out_writes_bytes_all_(_Size) void* _Dst,
    _In_reads_bytes_(_Size)       void const* _Src,
    _In_                          size_t      _Size
    );

Simpler:

void *memcpy(void *dest, const void *src, size_t count);

Parameters not elaborate here.

example:

std::string CopyString(const std::string &strBody)
{
    int nLen = strBody.length();
    char *cBody = new char(nLen);
    memcpy(cBody, strBody.c_str(), nLen);
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    system("pause");
    return 0;
}

The above function, an error will not occur in most cases, but there is a potential trap.

trap

Memory copy of the end of the string will not '\0'be checked

result

After the copy, garbled at the end of the string.

solution

When applying a multi-bytes of memory for memory, in order to ensure that the end of string copied into.

std::string CopyString(const std::string &strBody)
{
    int nLen = strBody.length();
    char *cBody = new char(nLen + 1);
    memcpy(cBody, strBody.c_str(), nLen + 1);
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    delete strReturn.c_str();
    system("pause");
    return 0;
}

Copy String strcpy

Function prototype

char* __cdecl strcpy(
    _Out_writes_z_(_String_length_(_Source) + 1) char*       _Dest,
    _In_z_                                       char const* _Source
    );

Simpler:

char *strcpy(char *dst, const char *src);

example

std::string CopyString(const std::string &strBody)
{
    int nLen = strBody.length();
    char *cBody = new char(nLen);
    strcpy(cBody, strBody.c_str());
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    delete strReturn.c_str();
    system("pause");
    return 0;
}

Explanation

strcpyDedicated to the string copy function, and the memcpydifference is that it will detect the end of the character '\0', so that the memory in the application do not apply excess.

The method of copy string string :: copy

prototype

    size_type copy(_Out_writes_(_Count) _Elem * const _Ptr,
        size_type _Count, const size_type _Off = 0) const
        {   // copy [_Off, _Off + _Count) to [_Ptr, _Ptr + _Count)
        auto& _My_data = this->_Get_data();
        _My_data._Check_offset(_Off);
        _Count = _My_data._Clamp_suffix_size(_Off, _Count);
        _Traits::copy(_Ptr, _My_data._Myptr() + _Off, _Count);
        return (_Count);
        }

Or a simple point:

size_t copy (char* s, size_t len, size_t pos = 0) const;

Here to explain these parameters:
S
pointer to a set of characters.
This array should contain sufficient storage space for the characters to copy.
len
number of characters to be copied (if the string is shorter, as many characters are copied).
pos
the position of the first character to copy.
If this is greater than the length of the string, it throws out_of_range.
Note: The first character string is represented by a value of 0 (not 1).

example

// string::copy
#include <iostream>
#include <string>

int main ()
{
  char buffer[20];
  std::string str ("This is a Test");
  std::size_t length = str.copy(buffer,6,5);
  std::cout << "buffer contains: " << buffer << '\n';
  return 0;
}

Trap & results

Because this copyfunction is still the final call memcopy, so the same trap, after the copy is complete, it will bring back a bunch of gibberish string

solution

At the end of copying, plus terminator '\0'.

// string::copy
#include <iostream>
#include <string>

int main ()
{
  char buffer[20];
  std::string str ("This is a Test");
  std::size_t length = str.copy(buffer,6,5);
  buffer[length]='\0';
  std::cout << "buffer contains: " << buffer << '\n';
  return 0;
}

Here there is a way, but this approach to be discussed, because my current results are correct. That is in the memory after the application, the first time to initialize, so it will not appear garbled copy.
E.g:

std::string CopyString(const std::string &strBody)
{
    char *cBody = NULL;
    int nLen = strBody.size();
    cBody = (char *)malloc(nLen);
    memset(cBody, 0, nLen);
    strBody.copy(cBody, nLen, 0);
    std::cout << "FONCTION:" << cBody << std::endl;
    return cBody;
}

int main()
{
    std::string strBody = "This is a Test!";
    std::string strReturn = CopyString(strBody);
    std::cout << "MAIN:" << strReturn.c_str() << std::endl;
    system("pause");
    return 0;
}

Afterword

In our development process, a lot of details we need to scrutiny, attention to detail, not to touch the issue, a problem, even problems are easy to find, especially in large projects.

Guess you like

Origin blog.csdn.net/weixin_34411563/article/details/90970575