【问题标题】:Value of char array changing, upon calling strcpy on a different char array在不同的 char 数组上调用 strcpy 时,char 数组的值发生变化
【发布时间】:2020-05-09 18:56:22
【问题描述】:

在尝试将字符串复制到 C 样式数组的方法时,由于一些奇怪的限制,我偶然发现了这种奇怪的行为,首先尝试使用 std::string::copy() 复制字符串似乎工作正常,直到我尝试复制相同的使用std::strcpy() 将另一个变量中的字符串转换为另一个空的 C 样式数组,然后第一个数组中的内容会从字符串中获取一些剩余内容。

#include <iostream>
#include <string>
#include <algorithm>
#include "string.h"

int main()
{
    std::string str = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";
    std::string str2 = "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l";

    char cstr[64] = {0};
    char cstr2[64] = {0};

    str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));

    // cstr:  "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
    std::cout << "cstr:  \"" << cstr << "\"" << std::endl;

    strcpy(cstr2, str2.c_str());
    cstr2[sizeof(cstr2) / sizeof(cstr2[0]) - 1] = '\0';

    // cstr:  "m nonumy eirmod tempor invidunt ut l"
    std::cout << "cstr:  \"" << cstr << "\"" << std::endl;

    // cstr2: "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed di"
    std::cout << "cstr2: \"" << cstr2 << "\"" << std::endl;    
    return 0;
}

当然,我只是在这里遗漏了一些愚蠢的关键点。

【问题讨论】:

  • strcpy(cstr2, str2.c_str()); 将超出cstr2 的范围,您将有未定义的行为
  • @Someprogrammerdude 啊,有道理!我从一开始就想知道这里是否会出现问题。

标签: c c++11 c-strings strcpy strncpy


【解决方案1】:

第一种情况

str.copy(cstr, std::min(str.size(), sizeof(cstr) / sizeof(cstr[0]) - 1));

您通过sizeof( cstr ) - 1 的值限制了复制的字符数。

所以数组cstr 包含一个字符串,因为它是零初始化的。

在第二种情况下,您没有限制复制的字符数。

strcpy(cstr2, str2.c_str());

因此数组cstr2 之外的内存被覆盖,因为str2.c_str() 指向的字符串包含的字符比数组cstr2 的大小要多。

你可以写

strncpy( cstr2, str2.c_str(), sizeof( cstr2 ) - 1 );

使用函数strncpy

【讨论】:

    【解决方案2】:

    strcpy(cstr2, str2.c_str());未定义的行为,因为它试图复制超过 64 个字节。

    其余代码无关紧要。

    Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut l
    1234567890123456789012345678901234567890123456789012345678901234
    

    【讨论】:

      猜你喜欢
      • 2014-03-23
      • 1970-01-01
      • 1970-01-01
      • 2013-03-17
      • 2018-08-20
      • 2011-08-04
      • 2020-07-06
      • 1970-01-01
      • 2019-08-22
      相关资源
      最近更新 更多