2015-07-06 2 views
0

программы:Начальный размер динамической памяти для программы

#include<stdio.h> 
#include<sys/types.h> 
#include<malloc.h> 
main() 
{ 
    int *i1, *i2; 
    char *s; 
    printf("sbrk(0) before malloc(4): %x\n", sbrk(0)); 
    i1 = (int *) malloc(sizeof(int)); 
    printf("sbrk(0) after `i1 = (int *) malloc(4)': %x\n", sbrk(0)); 
    i2 = (int *) malloc(sizeof(int)); 
    printf("sbrk(0) after `i2 = (int *) malloc(4)': %x\n", sbrk(0)); 
} 

Выход:

sbrk(0) before malloc(4): a027000 
sbrk(0) after `i1 = (int *) malloc(4)': a048000 
sbrk(0) after `i2 = (int *) malloc(4)': a048000 

что начальный размер кучи памяти для указанной программы. Я думаю, на начальном этапе программы начальный и конечный адреса кучи такие же. Однажды мы называем malloc, он выделяет память с помощью sbrk.

Вышеупомянутая программа показывает, что сначала sbrk (0) возвращает a027000 в качестве разрыва программы. После выполнения инструкции malloc разрыв программы изменяется на a048000. Он показывает, что до вызова malloc куча не имеет достаточного количества памяти. Таким образом, только перерыв программы изменяется после вызова malloc. При начальном состоянии , если в куче было достаточно памяти, нет необходимости изменять разрыв программы. Поэтому сначала размер кучи равен нулю. Это правильно?

+3

Хороший ответ зависит от архитектуры - пожалуйста, сообщите нам свою ОС и оборудование. В зависимости от вашей ОС у вас, вероятно, есть своего рода трассировка - вы можете запустить свою программу под трассировкой. Вероятно, вы увидите вызовы в семействе системных вызовов brk() как часть запуска. malloc использует биннинг кучи на некоторых системах - это означает, что у него есть свой кусок кучи, отдельный от libc. –

+1

Ваши 'printf()' -специалисты ошибочны. '% x' ожидает аргумент типа' unsigned int', а 'sbrk()' возвращает 'void *'. – EOF

+0

Вам также необходимо определить, когда должен измеряться «начальный» размер. До того, как будет вызван вызов 'main()', может выполняться бит кода. –

ответ

1

Что происходит, зависит от того, что ваш O/S делает до того, как вызывается main().

В Mac OS X имеется огромное количество памяти, которое происходит до того, как вы вызываете функцию main(). В настоящее время у меня есть список из 18 или около того подавленных «злоупотреблений памяти», которые все из вещей, которые происходят до того, как код запуска, предоставленный системой, вызывает main().

Запуск простую программу, которая печатает свои аргументы по одному в каждой строке, но не дает ему никаких аргументов, так что это не выход, дает отчет об использовании от valgrind так:

==59405== Memcheck, a memory error detector 
==59405== Copyright (C) 2002-2013, and GNU GPL'd, by Julian Seward et al. 
==59405== Using Valgrind-3.11.0.SVN and LibVEX; rerun with -h for copyright info 
==59405== Command: /Users/jleffler/bin/al 
==59405== 
--59405-- /Users/jleffler/bin/al: 
--59405-- dSYM directory is missing; consider using --dsymutil=yes 
--59405-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option 
--59405-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 2 times) 
--59405-- UNKNOWN mach_msg unhandled MACH_SEND_TRAILER option (repeated 4 times) 
==59405== 
==59405== HEAP SUMMARY: 
==59405==  in use at exit: 34,808 bytes in 417 blocks 
==59405== total heap usage: 517 allocs, 100 frees, 41,784 bytes allocated 
==59405== 
==59405== LEAK SUMMARY: 
==59405== definitely lost: 16 bytes in 1 blocks 
==59405== indirectly lost: 0 bytes in 0 blocks 
==59405==  possibly lost: 13,002 bytes in 109 blocks 
==59405== still reachable: 21,790 bytes in 307 blocks 
==59405==   suppressed: 0 bytes in 0 blocks 
==59405== Rerun with --leak-check=full to see details of leaked memory 
==59405== 
==59405== For counts of detected and suppressed errors, rerun with: -v 
==59405== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 0 from 0) 

Код для программы?

#include <stdio.h> 
#include <stdlib.h> 

int main(int argc, char **argv) 
{ 
    if (argc > 1) 
    { 
     while (*++argv) 
      puts(*argv); 
    } 
    return(EXIT_SUCCESS); 
} 

Много активности в памяти, но ничего из этого кода я не написал. Утечка - это номер, который я зарегистрировал в файле подавления.

0

При установке glibc debuginfo (например, на Fedora 22: dnf debuginfo-install glibc-2.21-5.fc22.x86_64) можно распечатать main_arena и mp_.

Отладка программы с пустым int main(void):

mp_.sbrk_base является основой кучи. В моей Linux, когда main был назван кучей, не существует. После звонка malloc(1000)mp_.sbrk_base является 0x602000. main_arena.top - свободный кусок памяти в верхней части кучи. Это 0x6023f0

(gdb) b main 
Breakpoint 1 at 0x4004fa: file test.c, line 3. 
(gdb) r 
Starting program: /home/m/a.out 

Breakpoint 1, main() at test.c:3 
3  return 0; 
(gdb) p mp_ 
$1 = {trim_threshold = 131072, top_pad = 131072, mmap_threshold = 131072, arena_test = 8, arena_max = 0, n_mmaps = 0, 
    n_mmaps_max = 65536, max_n_mmaps = 0, no_dyn_threshold = 0, mmapped_mem = 0, max_mmapped_mem = 0, max_total_mem = 0, 
    sbrk_base = 0x0} 
(gdb) p main_arena 
$2 = {mutex = 0, flags = 0, fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, top = 0x0, 
    last_remainder = 0x0, bins = {0x0 <repeats 254 times>}, binmap = {0, 0, 0, 0}, next = 0x7ffff7dd6b20 <main_arena>, 
    next_free = 0x0, system_mem = 0, max_system_mem = 0} 
(gdb) call malloc(1000) 
$3 = (void *) 0x602010 
(gdb) p mp_ 
$4 = {trim_threshold = 131072, top_pad = 131072, mmap_threshold = 131072, arena_test = 8, arena_max = 0, n_mmaps = 0, 
    n_mmaps_max = 65536, max_n_mmaps = 0, no_dyn_threshold = 0, mmapped_mem = 0, max_mmapped_mem = 0, max_total_mem = 0, 
    sbrk_base = 0x602000 ""} 
    (gdb) p main_arena 
$5 = {mutex = 0, flags = 1, fastbinsY = {0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, top = 0x6023f0, 
    last_remainder = 0x0, bins = {0x7ffff7dd6b78 <main_arena+88>, 0x7ffff7dd6b78 <main_arena+88>, [...] 
0x7ffff7dd7198 <main_arena+1656>, 0x7ffff7dd71a8 <main_arena+1672>, 0x7ffff7dd71a8 <main_arena+1672>...}, binmap = {0, 
0, 0, 0}, next = 0x7ffff7dd6b20 <main_arena>, next_free = 0x0, system_mem = 135168, max_system_mem = 135168} 

(gdb) call sbrk(0) 
$6 = 6434816 
(gdb) p (void*)$6 
$7 = (void *) 0x623000 
(gdb)