Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Программирование под Unix/Linux > Как выделить память в куче (heap) и проверить это?


Автор: HappyCoder 31.5.2007, 21:34
Что-то непонятное получилось. Или я чего-то не понимаю. Память была выделена в стеке. Как выделить её в куче? Пробовал выделять больше, но всё равно в стеке выделяется. WTF?

Код

$ valgrind --tool=massif ./realloc
...
==12198== 
==12198== Total spacetime:   2,212,548 ms.B
==12198== heap:               0.0%
==12198== heap admin:         0.0%
==12198== stack(s):          99.8%


Код

realloc.c:
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>

void checkp(void * p)
{
    if( p == NULL ) {
        printf("ERROR: Not enough memory\n");
        exit(1);
    }    
}

int main( int argc, char ** argv )
{
    //Store one number
    int n = 1;
    uint8_t *p;
    p = (uint8_t *) malloc(n * sizeof(uint8_t)); checkp(p);
    
    //Let's count
    int i;
    for(i=1; i<=255; i++)
    {
        if(i > n){
            //We need more memory
            n *= 2;
            uint8_t *np;
            np = (uint8_t *) realloc(p, n * sizeof(uint8_t)); checkp(np);
            printf("Reallocated memory to %i bytes. Memory address:%i\n", n * sizeof(uint8_t), np);
            p = np;
        }
        
        p[i-1] = i;
        printf("p[%i] = %u\n", i-1, p[i-1]);
    }

    free(p);
    return 0;
}

Автор: archimed7592 31.5.2007, 21:41
Цитата(HappyCoder @  31.5.2007,  21:34 Найти цитируемый пост)
Память была выделена в стеке.
неа... выдели мегов 10 - увидишь

Автор: HappyCoder 31.5.2007, 22:06
Цитата(archimed7592 @ 31.5.2007,  21:41)
Цитата(HappyCoder @  31.5.2007,  21:34 Найти цитируемый пост)
Память была выделена в стеке.
неа... выдели мегов 10 - увидишь

Выделил 40 мегов разом и увидел smile
Код

uint32_t *p = (uint32_t *) malloc(sizeof(uint32_t) * 1024 * 1024 * 10); //40 mb :-)
checkp(p);
free(p);


Но с realloc что-то не получается. Пишет, что в стеке. Выделил 32 мега. Я неправильно пользуюсь valgrind-ом?
Код

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

void checkp(void * p)
{
    if( p == NULL ) {
        printf("ERROR: Not enough memory\n");
        exit(1);
    }    
}

int main( int argc, char ** argv )
{
    //Store one number
    int n = 1;
    uint16_t *p;
    p = (uint16_t *) malloc(n * sizeof(uint16_t)); checkp(p);
    
    //Let's count
    int i;
    for(i=1; i<=24; i++)
    {
        if(1){
            //We need more memory
            n *= 2;
            uint16_t *np;
            np = (uint16_t *) realloc(p, n * sizeof(uint16_t)); checkp(np);
            printf("Reallocated memory to %f MB. Memory address:%u\n", n * sizeof(uint16_t) / 1024.0 / 1024.0, np);
            p = np;
        }
        
        p[i-1] = i;
        printf("p[%i] = %u\n", i-1, p[i-1]);
    }

    free(p);
    return 0;
}

Автор: MAKCim 1.6.2007, 08:50
Цитата(HappyCoder @  31.5.2007,  22:06 Найти цитируемый пост)
Пишет, что в стеке

не в стеке
Код

p = (uint16_t *) malloc(n * sizeof(uint16_t)); checkp(p);

напиши вывод
Код

printf("%p\n", p);

Автор: archimed7592 1.6.2007, 08:53
а лучше
Код
printf("%p\n%p\n", &p, p);

Автор: MAKCim 1.6.2007, 09:06
обычно виртуальное адресное пространство процесса (0x00000000 - 0xBFFFFFFF) распределяется следующим образом
---------------------------------------- 0xBFFFFFFF
Динамические библиотеки
----------------------------------------
STACK (растет вниз)




HEAP (растет вверх)
----------------------------------------
BSS
----------------------------------------
DATA
----------------------------------------
Разные секции (GOT, RODATA, ...)
----------------------------------------
CODE
----------------------------------------
Разные секции (INTERP, HASH, ...)
----------------------------------------
NULL
---------------------------------------- 0x00000000
т. е для радовой программы "дыра" между вершиной кучи и низом стека очень большая

Автор: HappyCoder 1.6.2007, 12:53
Код

Reallocated memory to 4 bytes. Memory address:0x501010
Reallocated memory to 8 bytes. Memory address:0x501010
Reallocated memory to 16 bytes. Memory address:0x501010
Reallocated memory to 32 bytes. Memory address:0x501010
Reallocated memory to 64 bytes. Memory address:0x501010
Reallocated memory to 128 bytes. Memory address:0x501010
Reallocated memory to 256 bytes. Memory address:0x501010
Reallocated memory to 512 bytes. Memory address:0x501010
Reallocated memory to 1024 bytes. Memory address:0x501010
Reallocated memory to 2048 bytes. Memory address:0x501010
Reallocated memory to 4096 bytes. Memory address:0x501010
Reallocated memory to 8192 bytes. Memory address:0x501010
Reallocated memory to 16384 bytes. Memory address:0x501010
Reallocated memory to 32768 bytes. Memory address:0x501010
Reallocated memory to 65536 bytes. Memory address:0x501010
Reallocated memory to 131072 bytes. Memory address:0x501010
Reallocated memory to 262144 bytes. Memory address:0x2ac987d77010
Reallocated memory to 524288 bytes. Memory address:0x2ac987d77010
Reallocated memory to 1048576 bytes. Memory address:0x2ac988094010
Reallocated memory to 2097152 bytes. Memory address:0x2ac988094010
Reallocated memory to 4194304 bytes. Memory address:0x2ac988094010
Reallocated memory to 8388608 bytes. Memory address:0x2ac988094010
Reallocated memory to 16777216 bytes. Memory address:0x2ac988094010
Reallocated memory to 33554432 bytes. Memory address:0x2ac988094010
Reallocated memory to 67108864 bytes. Memory address:0x2ac988094010

это при:
Код

    //Let's count
    int i;
    for(i=1; i<=25; i++)
    {
        if(1){
            //We need more memory
            n *= 2;
            uint16_t *np;
            np = (uint16_t *) realloc(p, n * sizeof(uint16_t)); checkp(np);
            printf("Reallocated memory to %u bytes. Memory address:%p\n", n * sizeof(uint16_t), np);
            p = np;
        }
        
        p[i-1] = i;
    }

    free(p);


Вывод этого:
Код

p = (uint16_t *) malloc(n * sizeof(uint16_t)); checkp(p);
printf("%p\n%p\n", &p, p);

такой:
Код

0x7fff22d72948
0x2ac988094010


Это адрес, по которому лежит указатель?
Код

printf("%p\n", &p);

Автор: MAKCim 1.6.2007, 14:39
Цитата(HappyCoder @  1.6.2007,  12:53 Найти цитируемый пост)
0x7fff22d72948
0x2ac988094010

ну вот, как можно видеть, ни а каком выделении в стеке речь не идет
кстати, адреса какие-то непонятные
я так понял, у тебя 64-х разрядная машина
почему тогда адреса не 64-х разрядные?

Автор: archimed7592 1.6.2007, 22:01
Цитата(HappyCoder @  1.6.2007,  12:53 Найти цитируемый пост)
Reallocated memory to 65536 bytes. Memory address:0x501010
Reallocated memory to 131072 bytes. Memory address:0x501010
Reallocated memory to 262144 bytes. Memory address:0x2ac987d77010
Reallocated memory to 524288 bytes. Memory address:0x2ac987d77010

по всей видимости malloc использует pool для небольших объектов...

Автор: HappyCoder 1.6.2007, 22:17
Цитата(MAKCim @ 1.6.2007,  14:39)
Цитата(HappyCoder @  1.6.2007,  12:53 Найти цитируемый пост)
0x7fff22d72948
0x2ac988094010

ну вот, как можно видеть, ни а каком выделении в стеке речь не идет
кстати, адреса какие-то непонятные
я так понял, у тебя 64-х разрядная машина
почему тогда адреса не 64-х разрядные?

Да, у меня Gentoo Linux x86_64 на AMD Turion ML-32 и gcc-4.1.2

Не знаю даже. Я особо не разбираюсь ещё. Во всяком случае, у меня указатели по 8 байт.

Автор: bsa 2.6.2007, 15:59
Цитата(HappyCoder @ 1.6.2007,  22:17)
Да, у меня Gentoo Linux x86_64 на AMD Turion ML-32 и gcc-4.1.2

Не знаю даже. Я особо не разбираюсь ещё. Во всяком случае, у меня указатели по 8 байт.

Все правильно. у тебя sizeof(long) == sizeof(void*) == 8.

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)