C 我想我超出了这个过程的可用内存。有人能看一下并核实一下吗?

C 我想我超出了这个过程的可用内存。有人能看一下并核实一下吗?,c,file,memory,memory-management,C,File,Memory,Memory Management,当我没有打开文件(180mb)时,我没有得到任何错误,但是当我打开文件时,我得到一个分段错误11。我相当肯定,我对这个过程的记忆已经超出了范围。有人有什么建议吗 我改变了参数。因此,如果NUM_TRAIN=10而不是60000,则不会出现分段错误。当NUM_TRAIN=60000,但我没有打开文件时,我也没有得到分段错误。当NUM_TRAIN=60000并且我打开文件时,我得到一个分段错误 #include <stdio.h> #define NUM_TRAIN 60000 #def

当我没有打开文件(180mb)时,我没有得到任何错误,但是当我打开文件时,我得到一个分段错误11。我相当肯定,我对这个过程的记忆已经超出了范围。有人有什么建议吗

我改变了参数。因此,如果NUM_TRAIN=10而不是60000,则不会出现分段错误。当NUM_TRAIN=60000,但我没有打开文件时,我也没有得到分段错误。当NUM_TRAIN=60000并且我打开文件时,我得到一个分段错误

#include <stdio.h>
#define NUM_TRAIN 60000
#define IMAGE_SIZE 784
#define TRAIN_IMAGES "mnist_train.csv"
int main()
{
  int arr[NUM_TRAIN][IMAGE_SIZE];
  int arr2[NUM_TRAIN];
  FILE* fTrain = fopen(TRAIN_IMAGES, "r");
  return 0;
}
#包括
#定义60000列的数量
#定义图像大小784
#定义列车图像“mnist\u TRAIN.csv”
int main()
{
int arr[列车数量][图像大小];
int arr2[列车数量];
文件*fTrain=fopen(列车图像,“r”);
返回0;
}

我不希望出现分段错误,但我是,特别是分段错误11

您正在堆栈上创建这些数组。与堆不同,它的容量受到严格限制,无法扩展。
1-8MB之间的限制是常见的

而是在堆上分配:

int **arr = malloc(sizeof(int *) * NUM_TRAIN);

for (int i=0; i < NUM_TRAIN; ++i)
{
   arr[i] = malloc(sizeof(int) * IMAGE_SIZE);
}
int**arr=malloc(sizeof(int*)*NUM\u列车);
对于(整数i=0;i

int
的二维数组实际上是指向
int
数组的指针数组


您应该在调用
malloc()
-此处省略的过程中检查错误

我解决了我的问题。基本上,我用数组分配了太多的静态内存,所以我修改了代码,将内存动态分配到堆中。代码如下:

#include <stdio.h>
#include <stdlib.h>
#define NUM_TRAIN 60000
#define IMAGE_SIZE 784
#define TRAIN_IMAGES "mnist_train.csv"
int main()
{
  int** arr = (int**)malloc(sizeof(int*)*NUM_TRAIN);
  for (int i = 0; i < NUM_TRAIN; i++)
    arr[i] = (int*)malloc(sizeof(int)*IMAGE_SIZE);
  int* arr2 = (int*)malloc(sizeof(int)*NUM_TRAIN);
  FILE* fTrain = fopen(TRAIN_IMAGES, "r");
  return 0;
}
#包括
#包括
#定义60000列的数量
#定义图像大小784
#定义列车图像“mnist\u TRAIN.csv”
int main()
{
int**arr=(int**)malloc(sizeof(int*)*列车数量);
对于(int i=0;i
使用malloc在堆上而不是堆栈上分配数组。或者,在main()之外定义数组,将其放入全局内存区域。对于简单的二维数组,不要使用
int**arr
。它浪费空间和时间。使用
int(*arr)[图像大小]
arr=malloc(NUM_TRAIN*sizeof*arr)
int
的二维数组实际上不是指向
int
@EricJ数组的指针数组。最有可能的是OP没有显示完整的代码,并且,当文件未打开时,OP也省略了将使用数组的代码,或者编译器能够推断出它们没有被使用,因此,编译器优化了数组的创建。然后不使用堆栈,因此不存在分段错误。@marko:Eric J.问的问题不是堆栈溢出的原因,而是文件是否打开导致堆栈溢出与否之间存在差异的原因。@JohnMancini:那么,正确的问题和答案需要发布文件的完整版本信息编译器和其他工具以及用于编译和运行的确切命令,可能还有足够的信息来重现输入文件,足以重现崩溃。如上所述,没有一个好的编译器会表现出所报告的行为差异;无论文件是否打开,它都会保留阵列(如果优化被禁用)并崩溃,或者删除阵列(如果优化被启用)并不会崩溃。对于简单的二维阵列,不要使用
int**arr
。它浪费空间和时间。使用
int(*arr)[图像大小]
arr=malloc(NUM_TRAIN*sizeof*arr)
.Re“我分配了太多的静态内存”:在函数中,int arr[NUM_TRAIN][IMAGE_SIZE];不分配静态内存;它分配自动内存,这通常是通过堆栈实现的。@EricPostpischil你能解释一下为什么这样更节省空间和时间吗?@JohnMancini,因为Eric的版本只需要一个
malloc()
调用(以后只需要一个
free()
),而不是
NUM\u TRAIN+1
,并且它只为所需的
int
s保留空间,而不为额外的
NUM\u列
指针保留空间。此外,访问所需的间接寻址更少,并且所有
int
s肯定位于单个连续块中,这可能有助于提高缓存的局部性。总之,Eric的版本要好得多。更不用说这两种方法产生的对象虽然可以使用相同的索引语法访问,但实际上是不同类型的。当您将它们作为函数参数以及其他地方传递时,差异就变得明显了。