информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
Портрет посетителяСтрашный баг в Windows
BugTraq.Ru
Русский BugTraq
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Модель надежности отказоустойчивой... 
 Oracle выпустила срочный патч для... 
 Атака на WPA2 
 Outlook полгода отправлял зашифрованные... 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
все доски
FAQ
IRC
новые сообщения
site updates
guestbook
beginners
sysadmin
programming
operating systems
theory
web building
software
hardware
networking
law
hacking
gadgets
job
dnet
humor
miscellaneous
scrap
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[Unix] STL и аллокация памяти [g++ 3.2.2] 29.11.04 11:52  Число просмотров: 1262
Автор: lunc <Alexander Krizhanovsky> Статус: Member
<"чистая" ссылка>
Проблеммный код:

#include <string.h>
#include <string>
#include <vector>

int
main ()
{
MEM_DEBUG_ON;

{
char test[1024];
memset (test, 'a', 1023);
test[1023]=0;

std::vector<std::string> vec;

for (int i=0; i<10; i++) {
std::string s1(test);
vec.push_back(s1);
}

vec.clear();
}

MEM_DEBUG_OFF;

return 0;
}


Код дебаггера памяти:
#include <stdio.h>
#include <malloc.h>
#include <stdlib.h>
#include <fcntl.h>

#define MAX_MALLOCS 10000
#define RES_FILE "./mem_allocs_stat"


/* Prototypes for our hooks. */
static void my_init_hook(void);
static void *my_malloc_hook(size_t, const void *);
static void my_free_hook(void *ptr, const void *caller);

static unsigned long mem_count;
static unsigned int addr_hash[MAX_MALLOCS][2];
static unsigned int hash_number;
FILE * f;

/* Variables to save original hooks. */
static void *(*old_malloc_hook)(size_t, const void *);
static void (*old_free_hook)(void *ptr, const void *caller);

/* Override initialising hook from the C library. */
void (*__malloc_initialize_hook) (void) = my_init_hook;

static void *
my_malloc_hook (size_t size, const void *caller) {
void *result;

__malloc_hook = old_malloc_hook;

result = malloc (size);

int i;
for (i=0; i<MAX_MALLOCS; i++) {
if ( !addr_hash[i][0] ) {
addr_hash[i][0] = (unsigned)result;
addr_hash[i][1] = size;
break;
}
}
if (i<MAX_MALLOCS)
hash_number++;
else
fprintf (f, "WARNING: too much mallocs\n");

old_malloc_hook = __malloc_hook;

fprintf (f, "malloc(%u) called from %p returns %p0\n",
(unsigned int) size, caller, result);

__malloc_hook = my_malloc_hook;

return result;
}


static void
my_free_hook (void *ptr, const void *caller)
{
__free_hook = old_free_hook;
free(ptr);

int i;
for (i=0; i<hash_number; i++) {
if (addr_hash[i][0] == (unsigned)ptr) {
addr_hash[i][0] = 0;
}
}
if (i==hash_number-1)
hash_number--;

old_free_hook = __free_hook;
fprintf (f, "free(%p0) called form %p\n", ptr, caller);
__free_hook = my_free_hook;
}


static void
print_result ()
{
for (int i=0; i<hash_number; i++)
if ( addr_hash[i][0] ) {
fprintf (f, "\t0x%x %d bytes\n", addr_hash[i][0], addr_hash[i][1]);
mem_count += addr_hash[i][1];
}
fprintf (f, "memory allocation result: %u\n", mem_count);

fclose (f);
}


#define MEM_DEBUG_ON mem_debug_activate()

#define MEM_DEBUG_OFF \
__malloc_hook = old_malloc_hook; \
__free_hook = old_free_hook


static void
mem_debug_activate ()
{
#ifdef DEBUG
f = fopen(RES_FILE, "w+");

if ( !!atexit(print_result) )
exit(-1);

old_malloc_hook = __malloc_hook;
__malloc_hook = my_malloc_hook;

old_free_hook = __free_hook;
__free_hook = my_free_hook;

#endif
}

Собственно просто смотрим выделение памяти.

Вывод дебаггера
Цитата

[lunc@kain temp]$ cat mem_allocs_stat
0 malloc(1136) called from 0x400b2e9e returns 0x805efe80 // выделение памяти для строки
1 malloc(320) called from 0x400b2e9e returns 0x805f4600 // ????
2 malloc(1136) called from 0x400b2e9e returns 0x805f5a80
3 malloc(1136) called from 0x400b2e9e returns 0x805fa200
4 malloc(1136) called from 0x400b2e9e returns 0x805fe980
5 malloc(1136) called from 0x400b2e9e returns 0x80603100
6 malloc(1304) called from 0x400b2e9e returns 0x80607880 // ????
7 malloc(1136) called from 0x400b2e9e returns 0x8060ca80
8 malloc(1136) called from 0x400b2e9e returns 0x80611200
9 malloc(1136) called from 0x400b2e9e returns 0x80615980
10 malloc(1136) called from 0x400b2e9e returns 0x8061a100
11 malloc(1136) called from 0x400b2e9e returns 0x8061e880
free(0x805efe80) called form 0x400b1983
free(0x805f5a80) called form 0x400b1983
free(0x805fa200) called form 0x400b1983
free(0x805fe980) called form 0x400b1983
free(0x80603100) called form 0x400b1983
free(0x8060ca80) called form 0x400b1983
free(0x80611200) called form 0x400b1983
free(0x80615980) called form 0x400b1983
free(0x8061a100) called form 0x400b1983
free(0x8061e880) called form 0x400b1983

Итого потреянно 1624 байта. Если сделать около 100 итреаций получится порядка 7Kb (добавляется еще одна аллокация, которая потом не освобождается).
Такое поведение возникает только при использовании push_back() (если создать вектор заранее с заданным размером, а потом пихать в него элементы -- память освободится полностью). С list та же история -- только аллокации другие.

Может быть я не правильно хуки поставил. Использовал mtrace:

@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x805f0b0 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x805f528 0x140 // 320
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x805f670 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x805fae8 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x805ff60 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x80603d8 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x8060850 0x518 // 1304
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x8060d70 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x80611e8 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x8061660 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x8061ad8 0x470
@ /usr/lib/libstdc++.so.5:(_Znwj+0x2e)[0x400b2e9e] + 0x8061f50 0x470
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x805f0b0
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x805f670
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x805fae8
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x805ff60
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x80603d8
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x8060d70
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x80611e8
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x8061660
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x8061ad8
@ /usr/lib/libstdc++.so.5:(_ZdlPv+0x23)[0x400b1983] - 0x8061f50

Таже самая память...

В чем дело? Можно ли пользовать для отладки программ с STL тулзы для дебаггинга malloc() (так понимаю new и delete реализованны через malloc и free)?
<programming> Поиск 
  • [Unix] STL и аллокация памяти [g++ 3.2.2] - lunc 29.11.04 11:52 [1262]








Rambler's Top100
Рейтинг@Mail.ru


  Copyright © 2001-2017 Dmitry Leonov   Page build time: 0 s   Design: Vadim Derkach