Segmentation fault error array in c [duplicate] - c

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 4 years ago.
I want to write a program in which I want to initialize integer array of size 987654321 for storing values of 1 and 0 only,
here is my program
#include <stdio.h>
#include <stdlib.h>
int main(){
int x,y,z;
int limit = 987654321;
int arr[limit];
for (x = 0;x < limit;x++){
printf("%d \n",arr[x]);
}
return 0;
}
but it gives segmentation fault

987654321 is certainly too big for a local variable.
If you need a dynamically sized array of that size you need to use malloc like:
int limit = 987654321;
int *arr = malloc(limit * sizeof(*arr));
if (arr == NULL)
{
... display error message and quit
}
...
free(arr); // free it once you're dont with the array
BTW are you aware that your array uses roughly 4 gigabytes of memory assuming the size of int is 4 on your platform?

Since you want to store values of 1 and 0 only, and these values require only one bit, you can use a bit array instead of an integer array.
The size of int is 4 bytes (32 bits) usually, so you can reduce the memory required by a factor of 32.
So instead of about 4 GB, you will only need about 128 MB of memory. Resources on how to implement a bit array can be found online. One such implementation is here.

Related

segmentation fault (core dumped) while huge number of for loops in c code [duplicate]

This question already has answers here:
Getting a stack overflow exception when declaring a large array
(8 answers)
Closed 10 months ago.
the following code caused segmentation fault (core dumped) with 1000000000 times loop.
but by reducing the looping time to 100000, it goes ok.
so is it causing any thing wrong in cpu, hardware, or anywhere? is it caused by watchdog timer?
can anybody help to explain it for this? what happened when cpu goes to huge loops(finite loops with huge number repeating)? how does cpu tell the computing is infinite? many thanks.
#include <stdio.h>
int main () {
int a[1000000000];
int i = 0;
for (i = 0;i < 1000000000; i++){
if(i % 4 == 0){
a[i] = i;
}else {
a[i] = 321;
}
}
printf("run over");
return 0;
}
The overflowing of the stack is observed here. 1000000000 * sizeof(int) memory is supposed to be there for storing this array. In short, the problem is coming from the size of the array not the number iterations.
You can either make the array static or dynamically allocate the memory.
Are you perhaps running out of memory ? Your 1 billion int array weighs 30 Gb if using 32bit ints.
This happened because stack has a memory limit. Your array will occupy a total of 1000000000 * sizeof(int) bytes, which will be equal to 3.725 Gigabytes on 64 bit machine.
You need to dynamically store the array on the heap memory like this:
int *array = malloc(1000000000 * sizeof(int));
Or, better break your array into several parts and process them and after processing store those results on a hard disk.
Also, you can see the maximum stack size on linux by using ulimit:
ulimit -s # stack size
ulimit -a # full details

Size of memory allocated for float in C

#include <stdio.h>
#define max_size 100
float array[max_size];
int n,counter;
int main(){
printf("Enter the size of the array...\n");
scanf("%d",&n);
for (counter=0; counter<n; counter++){
printf("%p\t",&array[counter]);
}
printf("\n\n");
return 0;
}
I am just experimenting with this C program and I am trying to verify that the size of a float is 8 bytes. But upon running this code with 5 elements in array, I get the address of these elements as following:
Enter the size of the array...
5
0x555555755040 0x555555755044 0x555555755048 0x55555575504c 0x555555755050
As you can see for the first float number, my system has allocated memory space ...40,41,42,43 which is 4 bits of space if I am not wrong. But the float data type is supposed to have 8 bytes of space for it. I am thinking that the program should have allocated memory space ...40,41,...4F for 2 bytes of space. So
...40-...4F //for first 2 bytes
...50-...5F //for second 2 bytes
...60-...6F //for third 2 bytes
...70-...7F //for last 2 bytes
So the second address would start at ...80. But this is not the result I am obtaining. What am I missing in this process? Thank you for the help !!
C standard does not say anything about the storage size of float and it has been purposely left out to the implementer.
Maybe on your system and compiler the size is 4. You can check that out by using sizeof(float). See also this discussion.

An issue while trying to print appended array elements in c

I was trying to make an array that contains Fibonacci numbers in C, but I got into trouble. I can't get all of the elements, and some of the elements are wrongly calculated, and I don't know where I am I going wrong.
#include <stdio.h>
int main(void){
int serie[]={1,1},sum=0,size=2;
while(size<=4000000){
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
Output:
1
2
4
6
11
17
28
45
73
118
191
309
500
809
1309
2118
3427
5545
8972
14517
23489
38006
61495
99501
160996
260497
421493
681990
1103483
1785473
2888956
4674429
7563385
12237814
19801199
32039013
51840212
83879225
135719437
219598662
355318099
574916761
930234860
1505151621
-1859580815
-354429194
2080957287
1726528093
-487481916
1239046177
751564261
1990610438
-1552792597
437817841
-1114974756
-677156915
-1792131671
1825678710
33547039
1859225749
1892772788
-542968759
1349804029
806835270
-2138327997
-1331492727
825146572
-506346155
318800417
-187545738
131254679
-56291059
74963620
18672561
93636181
112308742
205944923
318253665
524198588
842452253
1366650841
-2085864202
-719213361
1489889733
770676372
-2034401191
-1263724819
996841286
-266883533
729957753
463074220
1193031973
1656106193
-1445829130
210277063
-1235552067
-1025275004
2034140225
1008865221
-1251961850
-243096629
-1495058479
-1738155108
1061753709
-676401399
385352310
-291049089
94303221
-196745868
-102442647
-299188515
-401631162
-700819677
-1102450839
-1803270516
1389245941
-414024575
975221366
561196791
1536418157
2097614948
-660934191
--------------------------------
Process exited after 2.345 seconds with return value 3221225477
Press any key to continue . . .
I don't understand why it is giving that output.
int serie[]={1,1}
Declares an array of two elements. As the array has two elements and indices start from zero, it has valid indices - 0 and 1, ie. serie[0] is the first element and serie[1] is the second element.
int size=2;
while(..) {
serie[size]= ...
size+=1;
}
As size starts 2, the expression serie[2] = is invalid. There is no third element in the array and it writes to an unknown memory region. Executing such an action is undefined behavior. There could be some another variable there, some system variable, or memory of another program or it can spawn nasal demons. It is undefined.
If you want to store the output in an array, you need to make sure the array has enough elements to hold the input.
And a tip:
int serie[4000000];
may not work, as it will try to allocate 40000000 * sizeof(int), which assuming sizeof(int) = 4 is 15.2 megabytes of memory. Some systems don't allow to allocate that much memory on stack, so you should move to dynamic allocation.
You're having an integer overflow because the int size is ,at a certain leverl, not big enough to hold the numbers, so the number is wrapping round the size and giving false values.
Your program should be like:
#include <stdio.h>
int main(void){
long long unsigned series[100] = {1,1};
int size = 2;
while(size < 100){
series[size] = series[size-1] + series[size-2];
printf("%llu\n", series[size-1]);
size += 1;
}
return 0;
}
Although, size of long long unsigned is also limited, at a certain level, with such very big numbers in Fibonacci. So this will result in more correct numbers printed, but also will overflow at a certain level. It will overflow when the number exceeds this constant ULLONG_MAX declared in limits.h.
The problem with this code:
#include <stdio.h>
int main(void){
int serie[]={1,1},sum=0,size=2;
while(size<=4000000){
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
... is that it attempts to store a very long series of numbers (4 million) into a very short array (2 elements). Arrays are fixed in size. Changing the variable size has no effect on the size of the array serie.
The expression serie[size]=... stores numbers outside the bounds of the array every time it's executed because the only legal array index values are 0 and 1. This results in undefined behavior and to be honest you were lucky only to see weird output.
There are a couple of possible solutions. The one that changes your code the least is to simply extend the array. Note that I've made it a static rather than automatic variable, because your implementation probably won't support something of that size in its stack.
#include <stdio.h>
int serie[4000000]={1,1};
int main(void){
int size=2;
while(size<4000000){ // note strict less-than: 4000000 is not a valid index
serie[size]=serie[size-1]+serie[size-2];
printf("%d\n",serie[size-1]);
size+=1;
}
return 0;
}
The more general solution is to store the current term and the two previous terms in the series as three separate integers. It's a little more computationally expensive but doesn't have the huge memory requirement.
#include <limits.h>
#include <stdio.h>
int main(void)
{
int term0=0, term1=1, term2;
while(1)
{
if (term0 > INT_MAX - term1) break;// overflow, stop
term2 = term0 + term1;
printf("%d\n",term2);
term0 = term1;
term1 = term2;
}
return 0;
}
This also has the benefit that it won't print any numbers that have "wrapped around" as a result of exceeding the limits of what can be represented in an 'int`. Of course, you can easily choose another data type in order to get a longer sequence of valid output.
You have two problems:
You need to allocate more space in serie, as much as you are going
to use
Eventually the fib numbers will become too big to fit inside an integer, even a 64bit unsigned integer (long long unsigned), i think 90 or so is about max
See the modified code:
#include <stdio.h>
// Set maximum number of fib numbers
#define MAX_SIZE 90
int main(void) {
// Use 64 bit unsigned integer (can't be negative)
long long unsigned int serie[MAX_SIZE];
serie[0] = 1;
serie[1] = 1;
int sum = 0;
int size = 0;
printf("Fib(0): %llu\n", serie[0]);
printf("Fib(1): %llu\n", serie[1]);
for (size = 2; size < MAX_SIZE; size++) {
serie[size] = serie[size-1] + serie[size-2];
printf("Fib(%i): %llu\n", size, serie[size]);
}
return 0;
}
As you are only printing out the numbers, you don't actually have to store all of them
(only the two previous numbers), but it really doesn't matter if there's only 90.

Sizeof(Array) Prints wrong value [duplicate]

This question already has answers here:
How do I determine the size of my array in C?
(24 answers)
Closed 6 years ago.
I have initialized an array of size 10 but on printing the sizof array shows 40 . The code is as follows ,
#include <iostream>
using namespace std;
int main() {
int arr[10] = {2,4,5,6,7,8,9,6,90};
printf("%d \n" , sizeof(arr));
}
Output :
/Users/venkat/Library/Caches/CLion2016.1/cmake/generated/InsertionSort-e101b03d/e101b03d/Debug/InsertionSort
40
Process finished with exit code 0
What does C prints 40 here ?
sizeofreturns the size of the array in memory, not the length of the array. Then since sizeof(int) is 4 bytes and your array has 10 int values, its size is 40.
Your array contain 10 ints.
10 * sizeof(int)
int here is 32 bits = 4 bytes.
4*10 = 40. Simple math
Because sizeof is a built in operator that works on the type of the expression. For arrays (and not pointers) it will print sizeof(array_element_type) * array_length.
On your system, it must be that sizeof(int) is 4.
And once you get excited over learning that
sizeof(array)/sizeof(array[0]) == array_length
bear in mind that once you pass the array into a function, it will decay to a pointer and that will no longer hold.
You need to divide sizeof (arr) by the size of one element:
sizeof (arr)/ sizeof (arr[0])
This because sizeof(arr) shows the number of bytes the argument is made of, i.e. sizeof(int) * array dimention

sizeof dynamic array is not correct [duplicate]

This question already has answers here:
How to find the size of an array (from a pointer pointing to the first element array)?
(17 answers)
Closed 7 years ago.
In array there are four element so it size should be 4bit*4 = 16. (An int data type take 4 bit in my system to store the value.) But when i ran this code i only got 8 bit as the size of dynamicArray.
#include <stdio.h>
#include <stdlib.h>
int main(void) {
//Dynamic arrays save memory by creating a pointer that stores
//the beginning of the array
int *dynamicArray = malloc(20 * sizeof(int));
*dynamicArray = 10;
printf("Address %x stores value %d\n", dynamicArray, *dynamicArray);
dynamicArray[1] = 20;
printf("dynamicArray[1] stores value %d\n", dynamicArray[1]);
dynamicArray[2] = 45;
printf("dynamicArray[2] stores value %d\n", dynamicArray[2]);
dynamicArray[3] = 34;
printf("dynamicArray[3] stores value %d\n", dynamicArray[3]);
printf("The size of dynamicArray is %d\n", sizeof(dynamicArray));
// Release unused memory:
free(dynamicArray);
return EXIT_SUCCESS;
}
Here is the image of output.
Also suggest me website for C to check the in-built function properties or to know about them more.
Thank you.
You don’t have an array; you have a pointer.
The size of the pointer is measured in bytes, not bits.
sizeof is evaluated at compile time and is constant for any given expression or type. It does not depend on the number of “filled” elements in an array (or pointer to some space that holds those elements, for that matter).
Your expression is equivalent to sizeof(int*), and pointers are 8 bytes in your environment.
I ran your code on my 32-bit computer and the value of sizeof(dynamicArray) does report 4. I bet your computer is 64-bits which is why the value is 8 instead.
Take a look at: http://www.viva64.com/en/a/0004/ and look for the table titled "Table N2. 32-bit and 64-bit data models.". That would help explain why some systems report 4 and some report 8 for the value for sizeof(dynamicArray).

Resources