c++ - 大小为 1 的无效写入,地址 0x... 未堆栈、malloc 或(最近)释放 (Valgrind)

标签 c++ valgrind

我试图改变代码以不同的方式做我想做的事,但似乎没有解决 Valgrind 错误。

Cadena::Cadena(unsigned tam, char c):s_(new char[tam+1]), tam_(tam)
{
    //c is ' ' by default
    memset(s_, c, tam+1);
    s_[tam]='\0';
}
...
Cadena& Cadena::substr(unsigned i, unsigned tam) const
{
    if(i>=tam_||i+tam>tam_) throw out_of_range("Posicion indicada fuera de rango");
    Cadena* subCad=new Cadena(tam);
    strncpy(subCad->s_, &s_[i], tam);
    return *subCad;
}
==9669== Invalid write of size 1
==9669==    at 0x1390CC: Cadena::Cadena(unsigned int, char) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==    by 0x13972B: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==    by 0x12D436: test_cadena(_fctkern_t*) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==    by 0x137D42: main (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==  Address 0x105bc176f is not stack'd, malloc'd or (recently) free'd
==9669== 
==9669== 
==9669== Process terminating with default action of signal 11 (SIGSEGV)
==9669==  Access not within mapped region at address 0x105BC176F
==9669==    at 0x1390CC: Cadena::Cadena(unsigned int, char) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==    by 0x13972B: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==    by 0x12D436: test_cadena(_fctkern_t*) (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==    by 0x137D42: main (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==9669==  If you believe this happened as a result of a stack
==9669==  overflow in your program's main thread (unlikely but
==9669==  possible), you can try to increase the size of the
==9669==  main thread stack using the --main-stacksize= flag.
==9669==  The main thread stack size used in this run was 8388608.
其他方式:
Cadena& Cadena::substr(unsigned i, unsigned tam) const
{
    if(i>=tam_||i+tam>tam_) throw out_of_range("Posicion indicada fuera de rango");
    char res[tam+1];
    strncpy(res, s_+i, tam);
    res[tam]='\0';
    Cadena* subCad=new Cadena(tam);
    return *subCad;
}
==17029== Invalid write of size 1
==17029==    at 0x4C3304C: strncpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17029==    by 0x13979E: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==17029==  Address 0x1fff001000 is not stack'd, malloc'd or (recently) free'd
==17029== 
==17029== 
==17029== Process terminating with default action of signal 11 (SIGSEGV)
==17029==  Access not within mapped region at address 0x1FFF001000
==17029==    at 0x4C3304C: strncpy (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==17029==    by 0x13979E: Cadena::substr(unsigned int, unsigned int) const (in /mnt/hgfs/mvpoosf/P1/test-P1-auto)
==17029==  If you believe this happened as a result of a stack
==17029==  overflow in your program's main thread (unlikely but
==17029==  possible), you can try to increase the size of the
==17029==  main thread stack using the --main-stacksize= flag.
==17029==  The main thread stack size used in this run was 8388608.
我通过了这个测试(test-P1-auto):
  FCT_TEST_BGN(Cadena - Subcadena: tamanno mayor que longitud restante) {
    const Cadena a("0123456789");
    fct_chk_ex(out_of_range&, a.substr(9, 2));
  }
  FCT_TEST_END();
它返回数字 8 后面的两个元素的子字符串。这是不可能的,因为它抛出了 out_of_range,所以测试是可以的。但是当我使用 Valgrind 时,它给了我这些错误,我已经被困在这里好几个小时了。
我类(class) Cadena 的私有(private)部分:
private:
    char* s_;
    unsigned int tam_;

最佳答案

抱歉,伙计们犯了错误,但正如@Some程序员花花公子评论的那样,我没有在我的makefile上加上标志-g,它允许valgrind告诉我哪些行会出错。实际上那不是正确的测试,它是下一个:

FCT_TEST_BGN(Cadena - Subcadena: tamanno negativo) {
    const Cadena a("0123456789");
    fct_chk_ex(out_of_range&, a.substr(9, -1));
  }
  FCT_TEST_END();
正如我在这里看到的 Signed to unsigned conversion in C - is it always safe? ,没有办法得到一个无符号的负值并期望符号“只是被删除”。我通过将其更改为 int 并检查函数内部是否为负来解决它。
感谢大家的帮助。

关于c++ - 大小为 1 的无效写入,地址 0x... 未堆栈、malloc 或(最近)释放 (Valgrind),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63619658/

相关文章:

c++ - 重载运算符中的类型不匹配(编写管道)

c++ - 为什么GL_RASTERIZER_DISCARD无法使我写入模板缓冲区?

c++ - 配置文件花费的时间

c - Readdir/closedir - Valgrind 显示 "invalid read"

c - Valgrind 无效写入大小 8

c++ - 字符串 vector 仍然可以到达

c++ - SDL 2.0 TextInputEvent UTF8数据存储

c++ - 如何忽略 LNK2038(定义不匹配)?

c++ - 移动构造函数未按预期调用

c - 释放内存导致的 Valgrind 错误?