【问题标题】:Using strcpy() with dynamic memory将 strcpy() 与动态内存一起使用
【发布时间】:2023-04-07 21:19:01
【问题描述】:

我的代码运行正常并且没有内存泄漏。但是,我遇到了 valgrind 错误:

==6304== 14 errors in context 4 of 4:
==6304== Invalid write of size 1
==6304==    at 0x4A0808F: __GI_strcpy (mc_replace_strmem.c:443)
==6304==    by 0x401453: main (calc.cpp:200)
==6304==  Address 0x4c390f1 is 0 bytes after a block of size 1 alloc'd
==6304==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==6304==    by 0x401431: main (calc.cpp:199)

==6304== 4 errors in context 2 of 4:
==6304== Invalid read of size 1
==6304==    at 0x39ADE3B0C0: ____strtod_l_internal (in /lib64/libc-2.12.so)
==6304==    by 0x401471: main (calc.cpp:203)
==6304==  Address 0x4c390f1 is 0 bytes after a block of size 1 alloc'd
==6304==    at 0x4A075BC: operator new(unsigned long) (vg_replace_malloc.c:298)
==6304==    by 0x401431: main (calc.cpp:199)

除了起始地址之外,错误1和3分别与2和4相同

这些错误是什么意思,我该如何解决?

 int main(){

    //Dlist is a double ended list. Each Node has a datum,
    //a pointer to the previous Node and a pointer to the next Node
    Dlist<double> hold;
    Dlist<double>* stack = &hold;

    string* s = new string;
    bool run = true;
    while (run && cin >> *s){

        char* c = new char;
        strcpy(c, s->c_str());   //valgrind errors here

        if (isdigit(c[0]))
            stack->insertFront(atof(c));

        else{
            switch(*c){
                //calculator functions
            }

        delete c;
        c = 0;
  }
delete s;
s = 0;

【问题讨论】:

  • 问题是什么?
  • 为什么要动态分配内存?在上面的应用程序中应该没有理由这样做。
  • 一旦你的代码被修复,你可能应该在 codereview.stackexchange.com 上发帖,以获得关于实现目标的更好方法的意见。

标签: c++ valgrind dynamic-memory-allocation strcpy


【解决方案1】:

valgrind 会从 stdlib 函数中抛出许多通常无害的警告,因为它们有点“作弊”。但这不是这里的情况:

char* c = new char; // this is bad

只分配一个字符 - 不是字符缓冲区,试试:

char* c = new char[s->size()+1];

然后将删除改为:

delete [] c;

【讨论】:

    【解决方案2】:

    char* c = 新字符; c 的大小为 1,即使复制 1 个字符串,您也需要两个字符长缓冲区(第二个字符保存空终止符)

    【讨论】:

      【解决方案3】:

      就在这里:

          char* c = new char;
      

      您只分配了一个字符。而是分配一个数组:

          char* c = new char[str->length() + 1];
      

      还记得调用 delete[] 代替。您分配 +1 为字符串的空终止腾出空间。

      【讨论】:

        【解决方案4】:
            char* c = new char;
        

        您正在分配一个字符,然后将一个字符串复制到该内存中,该内存太长而无法容纳。你需要分配一个足够大的数组。

        【讨论】:

          猜你喜欢
          • 2016-07-30
          • 2013-02-08
          • 1970-01-01
          • 2012-03-12
          • 2018-11-29
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2017-04-09
          相关资源
          最近更新 更多