我正在完成一项任务(another question中的详细信息)。作为其中的一部分,我增加了数组的大小。并发现当我尝试初始化数组时:
int arr[2097152]; // 8MB
我有分段错误...我认为它是因为我试图声明一个太大的数组?然后我发现解决这个问题的方法是使用malloc
。但是对C来说是新手(主要使用JavaScript / Python / Java ......)。我对指针和东西很困惑......
我已经声明了一个8MB的数组:
int *arr = malloc (MBs * 1024 * 1024 / sizeof(int)); // MBs = 8
但是现在......我如何访问它或写入它?当我像arr
那样使用它时,我得到了地址,如果我使用*arr
,我会得到第一个元素?
答案 0 :(得分:8)
像arr[index]
一样使用它,就好像它被声明为数组一样。在C中,符号x[y]
完全等同于*(x + y)
。这适用于数组,因为数组名称转换为指向其第一个元素的指针。
int *arr = malloc (MBs * 1024 * 1024 / sizeof(int));
这不是一个好方法(并且没有达到你想要的大小),因为你没有方便的元素数量。您应该根据元素的数量来声明它,例如,
#define ARR_LENGTH 2097152
int *arr = malloc (ARR_LENGTH * sizeof *arr);
您需要乘以元素大小,因为malloc的参数是字节数。
答案 1 :(得分:5)
我认为是因为我试图声明一个太大的数组?
是的,的确如此。你最有可能在一个函数中这样做。其中阵列是在堆栈上的本地存储上创建的,通常堆栈不够大,无法满足这种大尺寸的需求。
通常的解决方案是使用动态内存。
如何访问或写入?当我像
arr
一样使用它时,我会收到地址,如果我使用*arr
,我会获得第一个元素吗?
您可以使用[]
运算符以与使用数组类似的方式访问它。
请注意,
arr[i] == i[arr] == *(arr + i) == *(i + arr)
所以,
arr[0] ---> Gives you first element
arr[1] ---> Gives you Second element
and so on...
请注意,数组的名称有时会衰减为指向其第一个元素的指针,但数组和指针并不相同!
好读:
答案 2 :(得分:2)
符号a[i]
与*(a + i)
相同(因此也与i[a]
相同,因为加法是可交换的)。由于指针算法和数组到指针衰减,您可以将此语法用于数组和指向数组元素:
int a[10];
int * b = a + 4;
int * c = malloc(sizeof(int) * 100);
a[2]; // third element of a
b[1]; // sixth element of a
c[3]; // fourth element of the array starting at c
free(c); // don't forget to clean up!
至于你的第一个问题:自动变量确实只有有限的空间可用。超出此空间称为...堆栈溢出。
答案 3 :(得分:2)
是的,您可以像 ARRAY 一样使用它。
int *arr = malloc (MBs * 1024 * 1024) ;
arr[0] = 1 ;
arr[6] = 675 ;
etc. ;
* arr = arr [0]; \ First element
答案 4 :(得分:2)
您还可以尝试将大数组作为静态变量放在堆栈区域之外。可能你不会再有段错误了。