std::map에 std::function을 넣고 실행하면 에러가 발생합니다.

삼구의신의 이미지


std::map에 member function pointer를 넣으려고 합니다. 컴파일은 잘 되는데, 실행중 에러가 발생합니다.

typedef std::function<void()> func;
typedef std::map<int,std::pair<func,int> > mapFunc;
typedef std::pair<func,int> pairFunc;
 
mapFunc funcList;
 
void Timer::addTimer(func f,int interval_ms,int funcKey)
{
	funcMutex.lock();
 
	int time = (int)(interval_ms/TIMER_INTERVAL);
 
	if(max_timer < time)
		max_timer = time;
 
	funcList.insert(std::pair<int,pairFunc >(funcKey, pairFunc(f,time)));
}

실행 중 오류 메세지 입니다.
*** glibc detected *** ./mu_app.elf: malloc(): memory corruption: 0x00130378 ***
======= Backtrace: =========
/lib/libc.so.6[0x40232f3c]
/lib/libc.so.6[0x40235c68]
/lib/libc.so.6(__libc_malloc+0xa8)[0x40237c4c]
./mu_app.elf[0xc38d0]
./mu_app.elf(_Znwj+0x2c)[0xc4658]
./mu_app.elf[0x2a614]
./mu_app.elf[0x2a2cc]
./mu_app.elf[0x29b2c]
./mu_app.elf[0x295fc]
./mu_app.elf[0x28f6c]
./mu_app.elf[0x286f8]
./mu_app.elf[0xe520]
./mu_app.elf[0xdef0]
./mu_app.elf[0xd794]
./mu_app.elf[0xd2d4]
./mu_app.elf[0x28034]
/lib/libpthread.so.0[0x4002c5f4]
/lib/libc.so.6(clone+0x88)[0x4028d368]
======= Memory map: ========
00008000-000f4000 r-xp 00000000 00:01 1399 /root/mu_app.elf
000fc000-000fd000 rwxp 000ec000 00:01 1399 /root/mu_app.elf
000fd000-003ca000 rwxp 00000000 00:00 0 [heap]
40000000-4001d000 r-xp 00000000 00:01 309 /lib/ld-2.8.so
4001d000-40024000 rwxp 00000000 00:00 0
40024000-40025000 r-xp 0001c000 00:01 309 /lib/ld-2.8.so
40025000-40026000 rwxp 0001d000 00:01 309 /lib/ld-2.8.so
40026000-4003a000 r-xp 00000000 00:01 264 /lib/libpthread-2.8.so
4003a000-40042000 ---p 00014000 00:01 264 /lib/libpthread-2.8.so
40042000-40043000 r-xp 00014000 00:01 264 /lib/libpthread-2.8.so
40043000-40044000 rwxp 00015000 00:01 264 /lib/libpthread-2.8.so
40044000-40046000 rwxp 00000000 00:00 0
40046000-4004c000 r-xp 00000000 00:01 259 /lib/librt-2.8.so
4004c000-40053000 ---p 00006000 00:01 259 /lib/librt-2.8.so
40053000-40054000 r-xp 00005000 00:01 259 /lib/librt-2.8.so
40054000-40055000 rwxp 00006000 00:01 259 /lib/librt-2.8.so
40055000-40109000 r-xp 00000000 00:01 344 /lib/libstdc++.so.6.0.17
40109000-40110000 ---p 000b4000 00:01 344 /lib/libstdc++.so.6.0.17
40110000-40114000 r-xp 000b3000 00:01 344 /lib/libstdc++.so.6.0.17
40114000-40116000 rwxp 000b7000 00:01 344 /lib/libstdc++.so.6.0.17
40116000-4011c000 rwxp 00000000 00:00 0
4011c000-401c1000 r-xp 00000000 00:01 262 /lib/libm-2.8.so
401c1000-401c8000 ---p 000a5000 00:01 262 /lib/libm-2.8.so
401c8000-401c9000 r-xp 000a4000 00:01 262 /lib/libm-2.8.so
401c9000-401ca000 rwxp 000a5000 00:01 262 /lib/libm-2.8.so
401ca000-402e7000 r-xp 00000000 00:01 268 /lib/libc-2.8.so
402e7000-402ee000 ---p 0011d000 00:01 268 /lib/libc-2.8.so
402ee000-402f0000 r-xp 0011c000 00:01 268 /lib/libc-2.8.so
402f0000-402f1000 rwxp 0011e000 00:01 268 /lib/libc-2.8.so
402f1000-402f4000 rwxp 00000000 00:00 0
402f4000-40300000 r-xp 00000000 00:01 312 /lib/libgcc_s.so.1
40300000-40307000 ---p 0000c000 00:01 312 /lib/libgcc_s.so.1
40307000-40308000 rwxp 0000b000 00:01 312 /lib/libgcc_s.so.1
40308000-4032b000 rwxp 00000000 00:00 0
403cc000-403cd000 ---p 00000000 00:00 0
403cd000-40bce000 rwxp 00000000 00:00 0
40bce000-40d0f000 rwxp 00000000 00:00 0
40e00000-40e21000 rwxp 00000000 00:00 0
40e21000-40f00000 ---p 00000000 00:00 0
beeef000-bef10000 rw-p 00000000 00:00 0 [stack]
Aborted

yhsuk의 이미지

대충 샘플을 만들어 돌려보았을 때에는 위 코드는 호출에 문제가 없었습니다.

c++11 을 사용해도 되는 환경이고, 직접 구현할 필요가 없으시면 thread timer 클래스 들이 좀 있을 겁니다.
코드리뷰를 부탁하는 글이긴 한데, 괜찮아 보이는 구현체가 있어서 링크 드립니다. 테스트해 보니 잘 되네요.

https://codereview.stackexchange.com/questions/40473/portable-periodic-one-shot-timer-implementation

아래는 쓰신 글에 대해서 테스트 해 본 코드입니다.

#include <iostream>
#include <utility>
#include <functional>
#include <map>
 
typedef std::function<void()> func;
typedef std::map<int, std::pair<func,int> > mapFunc;
typedef std::pair<func,int> pairFunc;
 
mapFunc funcList;
 
class Timer
{
public:
    void addTimer(func f,int interval_ms,int funcKey)
    {
        // funcMutex.lock();
 
        //int time = (int)(interval_ms/TIMER_INTERVAL);
 
        //if(max_timer < time)
        //    max_timer = time;
 
        funcList.insert(std::pair<int, pairFunc >(funcKey, pairFunc(f, interval_ms)));
    }
 
    void runTimers()
    {
        for(auto it = funcList.begin(); it != funcList.end(); ++it)
        {
            int interval_ms = (*it).second.second;
            std::cout << "interval_ms: " << interval_ms << std::endl;
            (*it).second.first();
        }
 
    }
};
 
void func1()
{
    std::cout << "func1() called" << std::endl;
}
 
void func2()
{
    std::cout << "func2() called" << std::endl;
}
 
void func3()
{
    std::cout << "func3() called" << std::endl;
}
 
 
int main()
{
    Timer timer;
 
    timer.addTimer(func1, 50, 1);
    timer.addTimer(func2, 100, 2);
    timer.addTimer(func3, 200, 3);
 
    timer.runTimers();
 
    return 0;
}

컴파일
g++ -std=c++11 main.cc

실행결과
interval_ms: 50
func1() called
interval_ms: 100
func2() called
interval_ms: 200
func3() called

Signature :) - "여유를 갖고 행동하되 게을러지지 말자"

삼구의신의 이미지

소스도 수정안했는데.. 갑자기 되네요 ㅠㅠ 더 찝찝하네요 ㅎㅎ

timer참고자료는 유용히 잘 쓰겠습니다

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.