информационная безопасность
без паники и всерьез
 подробно о проектеRambler's Top100
За кого нас держат?Сетевые кракеры и правда о деле ЛевинаСтрашный баг в Windows
BugTraq.Ru
Русский BugTraq
 Анализ криптографических сетевых... 
 Модель надежности двухузлового... 
 Специальные марковские модели надежности... 
 Бэкдор в xz/liblzma, предназначенный... 
 Три миллиона электронных замков... 
 Doom на газонокосилках 
главная обзор RSN блог библиотека закон бред форум dnet о проекте
bugtraq.ru / форум / programming
Имя Пароль
ФОРУМ
если вы видите этот текст, отключите в настройках форума использование JavaScript
регистрация





Легенда:
  новое сообщение
  закрытая нитка
  новое сообщение
  в закрытой нитке
  старое сообщение
  • Напоминаю, что масса вопросов по функционированию форума снимается после прочтения его описания.
  • Новичкам также крайне полезно ознакомиться с данным документом.
[Unix] STL и аллокация памяти [g++ 3.2.2] 29.11.04 11:52  
Автор: 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)?
1




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


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