C++ Valgrind犯了一个奇怪的错误

C++ Valgrind犯了一个奇怪的错误,c++,valgrind,C++,Valgrind,嗨,为什么我会遇到这个奇怪的Valgrind错误 ==18572== Memcheck, a memory error detector ==18572== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. ==18572== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info ==18572== Command: ./test ==18

嗨,为什么我会遇到这个奇怪的Valgrind错误

==18572== Memcheck, a memory error detector
==18572== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al.
==18572== Using Valgrind-3.10.0 and LibVEX; rerun with -h for copyright info
==18572== Command: ./test
==18572== 
==18572== Syscall param open(filename) points to unaddressable byte(s)
==18572==    at 0x42891B3: __open_nocancel (syscall-template.S:81)
==18572==    by 0x421E98B: _IO_file_open (fileops.c:227)
==18572==    by 0x421EB3A: _IO_file_fopen@@GLIBC_2.1 (fileops.c:332)
==18572==    by 0x421349A: __fopen_internal (iofopen.c:90)
==18572==    by 0x421350A: fopen@@GLIBC_2.1 (iofopen.c:103)
==18572==    by 0x8049141: main (test.cpp:46)
==18572==  Address 0x435c784 is 12 bytes inside a block of size 30 free'd
==18572==    at 0x402A808: operator delete(void*) (vg_replace_malloc.c:507)
==18572==    by 0x4109EC7: std::string::_Rep::_M_destroy(std::allocator<char> const&) (in /usr/lib/i386-linux-gnu/libstdc++.so.6.0.20)
==18572==    by 0x8049954: _M_dispose (basic_string.h:249)
==18572==    by 0x8049954: ~basic_string (basic_string.h:547)
==18572==    by 0x8049954: name() (test.cpp:39)
==18572==    by 0x8049127: main (test.cpp:46)
==18572== 
Private: 32164
Pss: 32234
Referenced: 33184
Rss: 33184
Shared: 1020
Swap: 0
==18572== 
==18572== HEAP SUMMARY:
==18572==     in use at exit: 88,560 bytes in 7,872 blocks
==18572==   total heap usage: 8,213 allocs, 341 frees, 96,854 bytes allocated
==18572== 
==18572== LEAK SUMMARY:
==18572==    definitely lost: 15,744 bytes in 3,936 blocks
==18572==    indirectly lost: 72,816 bytes in 3,936 blocks
==18572==      possibly lost: 0 bytes in 0 blocks
==18572==    still reachable: 0 bytes in 0 blocks
==18572==         suppressed: 0 bytes in 0 blocks
==18572== Rerun with --leak-check=full to see details of leaked memory
==18572== 
==18572== For counts of detected and suppressed errors, rerun with: -v
==18572== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 0 from 0)

首先,最重要的是:这是<>强>不是>强>好C++代码,甚至不像样。例如,您的一些

#include
是错误的,比如
应该是
。这里最糟糕的是那些使代码完全不可读的
#define
s。你<强>真正的< /强>应该读一个关于C++的!
为了更好的可读性,我制作了代码的预处理器输出(当然不包括在内)。看起来是这样的:

template<class A> std::string str(A a) { std::stringstream ss; ss<<a; return ss.str(); }
template<class A, class ... B> std::string str(A a, B...b) { std::stringstream ss; ss<<a<<str(b...); return ss.str(); }
template<class A, class X>
void add(std::map<std::string,int> &m, X x, A a) { if(strncmp(a,x,(new std::string(a))->length())==0)m[a] += atoi(strchr(x,':')+1);}
template<class A, class X, class ... B>
void add(std::map<std::string,int> &m, X x, A a, B...b) { if(strncmp(a,x,(new std::string(a))->length())==0)m[a] += atoi(strchr(x,':')+1); add(m, x, b...); }

const char* name() { return str("/proc/",getpid(),"/smaps").c_str(); }

int main(int __attribute__((unused)) argc, char __attribute__((unused)) *args[])
{
    char b[256];
    std::map<std::string,int> m;

    FILE *fp = fopen(name(), "r");
        while(fgets(b, 256, fp))
            add(m,b,"Rss","Shared","Private","Swap","Pss","Referenced");

        for(auto it : m) { auto a = it.first; auto b = it.second;
            int value = b;
            fprintf(stderr, "%s: %d\n", a.c_str(), b);
        }
    fclose(fp);

    return 1;
}
这是无效的,因为您将指向
name()
中本地
std::string
对象的内部缓冲区的指针传递给
fopen
。此对象在
name()
的末尾不再存在,因此指针不再指向有效内存


请注意,您的
add
方法中也存在内存泄漏:您的
new
up
std::string
对象从未被删除。

我知道我有一些错误。这就是我的原因asking@thohmy首先,关于代码错误的问题需要一个明确的问题陈述。但代码的真正问题是它的这种“糟糕”风格甚至难以调用C++。这简直是一团乱麻。我不想在这里侮辱你,我只是说,从一本好书中从头开始学C++,对你有最大的好处(参见上面的链接)。@ BaummitAugen有SSCCE:代码可能是从胡克。哇,你真好!Thanks@thohmy没问题。但是请采纳我的建议,学习如何写更好的C++。我保证,你现在所做的一切不会有任何结果。
template<class A> std::string str(A a) { std::stringstream ss; ss<<a; return ss.str(); }
template<class A, class ... B> std::string str(A a, B...b) { std::stringstream ss; ss<<a<<str(b...); return ss.str(); }
template<class A, class X>
void add(std::map<std::string,int> &m, X x, A a) { if(strncmp(a,x,(new std::string(a))->length())==0)m[a] += atoi(strchr(x,':')+1);}
template<class A, class X, class ... B>
void add(std::map<std::string,int> &m, X x, A a, B...b) { if(strncmp(a,x,(new std::string(a))->length())==0)m[a] += atoi(strchr(x,':')+1); add(m, x, b...); }

const char* name() { return str("/proc/",getpid(),"/smaps").c_str(); }

int main(int __attribute__((unused)) argc, char __attribute__((unused)) *args[])
{
    char b[256];
    std::map<std::string,int> m;

    FILE *fp = fopen(name(), "r");
        while(fgets(b, 256, fp))
            add(m,b,"Rss","Shared","Private","Swap","Pss","Referenced");

        for(auto it : m) { auto a = it.first; auto b = it.second;
            int value = b;
            fprintf(stderr, "%s: %d\n", a.c_str(), b);
        }
    fclose(fp);

    return 1;
}
FILE *fp = fopen(name(), "r");