【问题标题】:memcpy and _CrtlsValidHeapPointer(pUserData)memcpy 和 _CrtlsValidHeapPointer(pUserData)
【发布时间】:2013-12-24 16:43:20
【问题描述】:

我的 for 循环中的 memcpy 有问题 - 我需要将字符串转换为 *char:

for(i=0;i<10000;i++){
    char* Bchar = new char[Bi[i].length()+1];
    ZeroMemory(Bchar,Bi[i].length());
    memcpy(Bchar, Bi[i].c_str(), Bi[i].length()); //Exception on this row
    ...
    delete [] Bchar; 
}

exception的链接

【问题讨论】:

  • ZeroMemory 完全是对 CPU 周期的浪费,因为您将要对刚刚归零的数据中的每个 char 进行爆破。其次,如果大小与您描述的一样并且 B[i] 是有效对象(后者非常 重要),则您的memcpy 不能是错误的行。可能是 next 行出错,因为您永远不会终止您的字符串,因此任何依赖于所述终止的代码都会完全呕吐,或者B[i] 可能无效。
  • 基于各种cmets,我怀疑...部分代码可能存在其他问题。

标签: c++ string visual-studio char memcpy


【解决方案1】:

看起来您没有将字符串以零终止到新创建的Bchar 缓冲区中。根据您在复制到 Bchar 缓冲区后所做的操作,您很可能访问缓冲区末尾之后。

简单地使用 strcpy(或 strcpy_s)代替 ZeroMemory/memcpy。

【讨论】:

  • 我试试strcpy_s(Bchar,Bi[i].length(),Bi[i].c_str()); 还是一样的问题
  • 其实应该是Bi[i].length()+1
  • (中间参数是目标缓冲区的大小。)
【解决方案2】:

这段代码:

char* Bchar = new char[Bi[i].length()+1];
ZeroMemory(Bchar,Bi[i].length());

不会将最后一个字节归零。并且您不会在随后的memcpy 中复制该字节。

而不是ZeroMemory,只需使用标准C++,

char* Bchar = new char[ Bi[i].length()+1 ]();

但是,虽然这可以解决问题,但为什么不直接使用 std::vector 并让 管理内存?

string const& s = Bi[i];
vector<char>  Bchar( s.begin(), s.end() );

作为一般规则,将任何直接使用 newdelete 的行为视为恶臭。

【讨论】:

  • 这个解决方案解决了我的问题,但我需要使用库 TomLibMath 中的函数 - mp_read_radix(mp_int *a, const char *str, int radix) => 我需要数据类型 char *Bchar
  • @user3077025 你从c_str()得到数据类型const char*!喜欢这个mp_read_radix(..., Bi[i].c_str(), ...);。你太努力了,你不需要复制到一个新的字符串,你可以使用你已经得到的。
  • 约翰:mp_read_radix(..., Bi[i].c_str(), ...); => 有同样的问题
猜你喜欢
  • 2014-04-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
  • 2011-07-27
  • 1970-01-01
  • 1970-01-01
  • 2020-07-24
相关资源
最近更新 更多