Valgrind的越来越奇怪的错误
嗨为什么我收到这个奇怪的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
==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: [email protected]@GLIBC_2.1 (fileops.c:332)
==18572== by 0x421349A: __fopen_internal (iofopen.c:90)
==18572== by 0x421350A: [email protected]@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)
我想尝试让内存使用。这是我的代码:
#include <stdio.h>
#include <functional>
#include <string.h>
#include <unistd.h>
#include <stdlib.h>
#include <iostream>
#include <string>
#include <sstream>
#include <map>
#define rss_str "Rss"
#define shared_str "Shared"
#define private_str "Private"
#define swap_str "Swap"
#define pss_str "Pss"
#define referenced_str "Referenced"
#define sep ':'
#define readopenfile "r"
#define i int
#define s std::string
#define l(A) (new s(A))->length()
#define conc(...) str(__VA_ARGS__).c_str()
#define eq(A,B) strncmp(A,B,l(A))==0
#define fun(B) strchr(B,sep)+1
#define smap std::map<s,i>
#define foreach(m) for(auto it : m) { auto a = it.first; auto b = it.second;
#define foreachend }
#define strs std::stringstream
#define beginfile(F) FILE *fp = fopen(F(), readopenfile);
#define endfile fclose(fp);
template<class A> s str(A a) { strs ss; ss<<a; return ss.str(); }
template<class A, class ... B> s str(A a, B...b) { strs ss; ss<<a<<str(b...); return ss.str(); }
template<class A, class X>
void add(smap &m, X x, A a) { if(eq(a,x))m[a] += atoi(fun(x));}
template<class A, class X, class ... B>
void add(smap &m, X x, A a, B...b) { if(eq(a,x))m[a] += atoi(fun(x)); add(m, x, b...); }
const char* name() { return conc("/proc/",getpid(),"/smaps"); }
i main(i __attribute__((unused)) argc, char __attribute__((unused)) *args[])
{
char b[256];
smap m;
beginfile(name)
while(fgets(b, 256, fp))
add(m,b,rss_str,shared_str,private_str,swap_str,pss_str,referenced_str);
foreach(m)
i value = b;
fprintf(stderr, "%s: %d\n", a.c_str(), b);
foreachend
endfile
return 1;
}
没有Valgrind的我的程序工作正常:
所有的和最重要的Private: 1004
Pss: 1121
Referenced: 1952
Rss: 1952
Shared: 948
Swap: 0
第一:这是不良好的C++代码,甚至没有像样的。例如,你的一些#includes
是错误的,如<stdio.h>
应该是<cstdio>
。这里最糟糕的是#define
,它使您的代码完全无法读取。您真的应在C++上阅读good book!
为了更好的可读性我公司生产代码的预处理器输出(减去包括当然)。它看起来像这样:
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");
这是无效的,因为你在name()
一个指针传递给当地std::string
对象的内部缓冲区fopen
。该对象在name()
结束时不再存在,因此指针不再指向有效内存。
注意,也有内存泄漏在add
方法:你new
了std::string
对象永远不会被删除。
哇,真好!谢谢 – thohmy
@thohmy没问题。但* *请接受我的建议,并学习如何写出更好的C++。你现在正在做对你没好处,我保证。 –
我知道我有一些错误。这就是为什么我要求 – thohmy
@thohmy首先,关于代码错误的问题需要[SSCCE](http://www.sscce.org)以及明确的问题陈述。但是,你的代码的真正问题在于它是如此糟糕的“样式”,甚至很难调用C++。这只是一个难以理解的混乱。我不想在这里侮辱你,我只想说,这将是从使用一个像样的书从头学C++您的最佳利益(见上面的链接)。 –
@BaummitAugen他有SSCCE :)代码可能来自www.ioccc.org,这个问题可能是一个坏的笑话。 –