Malloc Failing на 64-битной версии Ubuntu - PullRequest
0 голосов
/ 16 февраля 2011

Я выполняю следующий код на 64-битном Ubuntu-боксе с 18 ГБ ОЗУ, и, как вы можете видеть, мой вызов Malloc завершается неудачно, когда я пытаюсь выделить 2 ^ 31 байт.Я не уверен, почему это происходит, или как это исправить (я пробовал флаги компилятора, а также calloc ()).Мне было интересно, может ли кто-нибудь объяснить мне, почему я не могу выделить больше места на 64-битном боксе и как я могу решить эту проблему.

#include <stdio.h>
#include <stdlib.h>
//#include "svm_model_matlab.h"
//include "svm.h"
#include <math.h>


struct svm_node
{
        int index;
        double value;
};


//#define Malloc(type,n) (type *)calloc(n,sizeof(type))
#define Malloc(type,n) (type *)malloc((n)*sizeof(type))

int main()
{

        int i;
        for(i =25; i< 35; ++i)
        {
                printf("2^%d %d \n", i,(long int) pow(2,i));
                svm_node* x_space = Malloc(struct svm_node,pow(2,i));
                printf("the address is %x\n", x_space);
                free(x_space);
        }


        return 0;
}

Вывод:

2^25 33554432
the address is 8513e010
2^26 67108864
the address is 6513e010
2^27 134217728
the address is 2513e010
2^28 268435456
the address is a513e010
2^29 536870912
the address is a513e010
2^30 1073741824
the address is 0
2^31 -2147483648
the address is 0
2^32 0
the address is 0
2^33 0
the address is 0
2^34 0
the address is 0

Обновление:

Я обнаружил проблему, с которой столкнулся: в настоящее время я запускаю свой код на EC2 в 64-битном дистрибутиве Ubuntu linux, а в стандартных боксах linux на EC2 0 мест подкачки.Это заставляло мой процесс вызывать ошибку, когда он запрашивал какой-либо объем памяти, превышающий физическую ОЗУ, потому что он не мог выполнять перелистывание страниц.После создания файла подкачки моя проблема исчезла.

Спасибо за помощь

1 Ответ

4 голосов
/ 16 февраля 2011

pow() - ужасный способ вычислить силы 2. Используйте 1 << i вместо.

Затем выберите тип данных, достаточно большой, чтобы вместить требуемый размер. Сейчас он переполняется размером int и поэтому пытается выделить отрицательное число байтов. Это не работает по понятным причинам.

Я подозреваю, что malloc(1ULL << 31) будет успешно работать в вашей системе без каких-либо проблем.

Далее, вы выделяете гораздо больше, чем 2 31 байт, которые упоминает ваш вопрос, вы фактически пытаетесь выделить 2 i * sizeof (svm_node), или около 2 я + 4 . Неудачное распределение с i=30 предназначено примерно для 16 ГБ, что вполне может быть больше, чем у вашей свободной ОЗУ.

Наконец, вы получаете 32-битные значения при печати указателей. Попробуйте printf("%p", x_space); вместо этого. Если это все еще дает 32-битные значения, попробуйте использовать 64-битный компилятор.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...