Malloc 在 64 位 Ubuntu 机器上失败
我在具有 18 GB RAM 的 64 位 Ubuntu 机器上运行以下代码,如您所见,当我尝试分配 2^31 字节时,对 Malloc 的调用失败。我不确定为什么会发生这种情况,或者如何修复它(我已经尝试过编译器标志和 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
更新:
我发现了我遇到的问题:我目前在 64 位 Ubuntu Linux 发行版上的 EC2 上运行我的代码,EC2 上的默认 Linux 盒子有 0 交换空间。这导致我的进程在请求超过物理 RAM 的内存量时出现段错误,因为它无法分页。创建交换文件后,我的问题就消失了。
感谢您的帮助
I am running the following code on a 64-bit Ubuntu box with 18 GB of RAM, and as you can see, my call to Malloc is failing when I try to allocate 2^31 bytes. I am not sure why this is happening, or how to fix it (i have tried compiler flags and also calloc()). I was wondering if someone can explain to me why I am not able to alloc more space on a 64-bit box and how I can fix this issue.
#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;
}
Output:
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
Update:
I found the issue I was having: I am currently running my code on EC2 on a 64-bit Ubuntu linux distro and the default linux boxes on EC2 have 0 swap space. This was causing my process to seg fault when it was requesting any amount of memory more than the physical RAM because it was not able to page. After I created a swap file, my problem went away.
Thanks for your help
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
pow()
是一种计算 2 幂的糟糕方法。使用1 <<我代替。
然后,选择一个足够大的数据类型来容纳您请求的大小。现在它溢出了
int
的大小,因此尝试分配负数的字节。由于显而易见的原因,这不起作用。我怀疑
malloc(1ULL << 31)
会在您的系统上成功,没有任何问题。接下来,您分配的空间远远超过问题提到的 231 字节,您实际上是在尝试分配 2i *
sizeof (svm_node),或大约 2i+4。失败的分配(
i=30
)大约为 16GB,这很可能超过您的可用 RAM。最后,打印指针时您将获得 32 位值。尝试使用
printf("%p", x_space);
代替。如果仍然给出 32 位值,请尝试使用 64 位编译器。pow()
is a horrible way to calculate powers of 2. Use1 << i
instead.Then, pick a data type big enough to hold your requested size. Right now it's overflowing the size of
int
, and therefore trying to allocate a negative number of bytes. That doesn't work for obvious reasons.I suspect that
malloc(1ULL << 31)
would succeed on your system with no issues whatsoever.Next, you're allocating far more than the 231 bytes your question mentions, you're actually trying to allocate 2i *
sizeof (svm_node)
, or about 2i+4. The failing allocation, withi=30
, is for roughly 16GB, which may very well be more than your free RAM.Finally, you're getting 32-bit values when printing pointers. Try
printf("%p", x_space);
instead. If that still gives you 32-bit values, try using a 64-bit compiler.