gpt4 book ai didi

c++ - Valgrind:抛出自定义异常时为 "invalid read size 1"

转载 作者:搜寻专家 更新时间:2023-10-31 01:37:38 26 4
gpt4 key购买 nike

我的程序工作正常,除非我在 valgrind 中运行它并使其抛出异常(我是故意这样做的,它取决于用户定义的参数)。

主要功能是:

int main(){
try{
// create objects
// call function
}
catch(std::exception const& e){
std::cerr << "ERROR: " << e.what() << std::endl;
}
return 0;
}

并且我没有在代码中使用任何其他“try ... catch” block 。

我定义了自己的异常类:

#ifndef CUSTOMEXCEPTION_H_INCLUDED
#define CUSTOMEXCEPTION_H_INCLUDED

#include <exception>


class TracedError : public std::exception
{
protected:
int line_;
std::string file_;
std::string description;

public:
TracedError(std::string const& file, int line, std::string const& desc)
throw():
line_(line),
file_(file),
description(desc)
{}

virtual const char* what() const throw(){
std::string msg;
msg = "File: " + file_ + " Line: " + std::to_string(line_) + " Message: " + description;
return msg.c_str();
}

virtual ~TracedError() throw() {}
};


#endif // CUSTOMEXCEPTION_H_INCLUDED

我这样调用异常:

throw TracedError(__FILE__,__LINE__,"Message of the exception");

我编译运行程序没有问题,异常出现在这种形式下:

ERROR: File: path/to/file.cpp Line: 106 Message: Message of the exception.

这正是我想要的。但是当我用 valgrind 运行它时,我得到一个错误:

ERROR: ==12664== Invalid read of size 1
==12664== at 0x4C2CC02: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12664== by 0x4ECED58: length (char_traits.h:263)
==12664== by 0x4ECED58: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (ostream:536)
==12664== by 0x441EC6: main (main.cpp:52)
==12664== Address 0x5a20b88 is 24 bytes inside a block of size 237 free'd
==12664== at 0x4C2B183: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12664== by 0x4422E1: TracedError::what() const (TracedError.h:25)
==12664== by 0x441EA9: main (main.cpp:52)
==12664==
==12664== Invalid read of size 1
==12664== at 0x4C2CC14: strlen (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12664== by 0x4ECED58: length (char_traits.h:263)
==12664== by 0x4ECED58: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (ostream:536)
==12664== by 0x441EC6: main (main.cpp:52)
==12664== Address 0x5a20b89 is 25 bytes inside a block of size 237 free'd
==12664== at 0x4C2B183: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12664== by 0x4422E1: TracedError::what() const (TracedError.h:25)
==12664== by 0x441EA9: main (main.cpp:52)
==12664==
==12664== Syscall param write(buf) points to unaddressable byte(s)
==12664== at 0x5753940: __write_nocancel (syscall-template.S:81)
==12664== by 0x56DBD2C: _IO_file_write@@GLIBC_2.2.5 (fileops.c:1302)
==12664== by 0x56DC4EE: new_do_write (fileops.c:537)
==12664== by 0x56DC4EE: _IO_file_xsputn@@GLIBC_2.2.5 (fileops.c:1384)
==12664== by 0x56D1E68: fwrite (iofwrite.c:43)
==12664== by 0x4ECE955: sputn (streambuf:451)
==12664== by 0x4ECE955: __ostream_write<char, std::char_traits<char> > (ostream_insert.h:50)
==12664== by 0x4ECE955: std::basic_ostream<char, std::char_traits<char> >& std::__ostream_insert<char, std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*, long) (ostream_insert.h:101)
==12664== by 0x4ECED66: std::basic_ostream<char, std::char_traits<char> >& std::operator<< <std::char_traits<char> >(std::basic_ostream<char, std::char_traits<char> >&, char const*) (ostream:535)
==12664== by 0x441EC6: main (main.cpp:52)
==12664== Address 0x5a20b88 is 24 bytes inside a block of size 237 free'd
==12664== at 0x4C2B183: operator delete(void*) (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.so)
==12664== by 0x4422E1: TracedError::what() const (TracedError.h:25)
==12664== by 0x441EA9: main (main.cpp:52)
==12664==
File: /home/ak/Documents/framework-v3/src/encoder.cpp Line: 106 Message: The evolution parameters are incorrect.
==12664==
==12664== HEAP SUMMARY:
==12664== in use at exit: 0 bytes in 0 blocks
==12664== total heap usage: 26 allocs, 26 frees, 1,292 bytes allocated
==12664==
==12664== All heap blocks were freed -- no leaks are possible
==12664==
==12664== For counts of detected and suppressed errors, rerun with: -v
==12664== ERROR SUMMARY: 114 errors from 3 contexts (suppressed: 0 from 0)

main.cpp: 52 指的是这一行:

std::cerr << "ERROR: " << e.what() << std::endl;

TracedError.h:25 指的是这一行:

return msg.c_str();

据我了解,它返回一个无效指针。但它在 valgrind 之外编译得很好,并打印出正确的消息。

是因为我没有在其他类/函数中使用“try ... catch” block 吗?我应该系统地捕获并重新抛出错误吗?

似乎要为已经工作的东西添加很多代码,所以我的问题是:这是否意味着我有一个可能导致破坏的未定义行为,或者我可以忽略 valgrind 错误吗?

最佳答案

From what I understand, it returns an invalid pointer. But it compiles fine outside of valgrind and prints the right message.

这并不意味着什么。您有未定义的行为,因此任何事情都可能发生(包括它似乎按预期工作)。

return msg.c_str(); 从局部变量返回指针,该指针在调用 TracedError::what() 后不复存在。这就是 valgrind 提示的原因。

您应该使 msg 成为异常类的成员变量,并在构造函数中构建消息字符串以解决此问题。

关于c++ - Valgrind:抛出自定义异常时为 "invalid read size 1",我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33873321/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com