【问题标题】:how can I use strcpy safely我怎样才能安全地使用 strcpy
【发布时间】:2012-10-02 03:50:56
【问题描述】:

我想将char* 分配给char*,如果我使用strcpy,我会遇到几个运行时内存问题,所以我通过使用= operator 的简单分配来解决它。 谁能解释一下在使用strcpy之前应该准备什么以避免内存问题。

编辑:

int Function(const char* K,char* FileIN,char* FileOut,int DC)
{   
    char *fic_in,*n_fic,*fic_out,*fic_dec;

    unsigned char k[17];

        fic_in = (char*)malloc(60*sizeof(char));

        strcpy((char*)k,K);

        //strcpy(fic_in,FileIN);  //I remove this one
        fic_in=FileIN;            //and replace it by this
      ...

【问题讨论】:

  • 由于技术问题,我们暂时无法读懂您的想法。请出示代码。
  • 您是否在目标 char* 中预先保留了必要的空间?根据引用 (cplusplus.com/reference/clibrary/cstring/strcpy):“为避免溢出,目标指向的数组的大小应足够长,以包含与源相同的 C 字符串(包括终止空字符),并且不应在内存中与源重叠。”
  • @WhozCraig:是的。顺便说一句,我从来没有说过“strncpy”,我也不建议使用它。这是非常不安全的;-)
  • 以防万一,以“安全”方式使用strncpy:buf[len-1] = 0; strncpy(buf, src, len); if (buf[len] != 0) report_error; 为例。它可能比使用strlen 检查memcpy 后面的长度更有效,但同样它也可能效率较低,尤其是当src 明显短于len 时。使用strlcpy 将是if (strlcpy(dst, src, len) >= len) report_error;,在我看来它开始像“安全”而不是“可以安全使用”的功能。

标签: c++ memory-management char strcpy


【解决方案1】:
const char *a = "string literal";
const char *b;

a 是一个指向字符串文字的指针。 b 是一个没有特别指向任何地方的指针(它是未初始化的)。

b = a;

b 现在指向 a 指向的同一内存。

char c[100];

c 现在是一个 100 个字符的数组。到目前为止,该内存区域与其他所有区域完全分开。

strcpy(c, a);

c 的内容(具体来说,前 15 个字节)现在与a 指向的内存保持相同的值。所以现在有 两个 内存区域包含相同的字符串数据。

如您所见,分配指针与strcpy 几乎没有共同之处。如果您想将char* 分配给char*,那么您不应该靠近strcpy。

阅读一本关于 C++ 的书是必不可少的,但strcpy 的基本要求是目标指针必须指向一个内存区域,该内存区域必须有足够的空间容纳源指针指向的字符串。可能您的“运行时内存问题”是因为您没有确保这一点,这就是您需要阅读书籍的原因。

【讨论】:

  • 感谢您的解释,分配指针和 strcpy 之间的区别对我来说很清楚,但我的问题是关于使用 strcpy 的问题以及如何取消它:)
  • @oumaya:在您显示的有限代码中无法准确说出问题所在。但答案就是我最后所说的,你必须从某处获得足够的空间。有不止一种方法可以做到这一点。
  • 是的,我的意思是为目录树中的每个文件递归地为其子目录调用此函数,所以我认为正如您所提到的,这一切都是为了在内存中拥有一个有效的指针和足够的空间: )
【解决方案2】:

简答:您根本不应该使用strcpy,而应该使用strncpy。后一个函数不依赖尾随的\0,并要求您提供最大复制长度。

此外,对于指针分配,您根本不需要strncpy。你想复制内存还是简单地重新分配指针?对于重新分配,= 运算符非常好。

【讨论】:

  • 也许是一个有用的评论,但根本不是一个正确的答案。当您应该使用指针赋值而不是任何库函数时,它无济于事。
  • 是的,我只是想澄清一下。
  • 我完全 +1 这个,但是@Gnosophilon,当简单地将一个 char* 分配给另一个 char* 时,什么时候需要一个 strncpy 不必要的? =) 在我的世界里,永远不会 =)
【解决方案3】:

char* 是指向字符串字符的指针。要制作副本,您需要先为其分配内存并运行副本。类似的东西

size_t l = strlen(src);
char *dst = malloc(l+1);
memmove(dst,src,l+1);

(如果 malloc 成功,则进行一些错误检查等)。

不过,考虑到您的问题被标记为c++,我建议您使用std::string 课程并同时进行一些阅读。了解事物的实际运作方式确实很有帮助。

【讨论】:

    【解决方案4】:

    您需要确保接收缓冲区足够大以容纳源字符串,包括末尾的终止'\0'-字符。原来如此。

    如果您可以将字符串表示为可以复制的 char * 指针,那很好,但并非总是可行。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-04-15
      • 1970-01-01
      • 2012-05-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多