Segmentation fault in test cases - c

So, the question is as follows:
Given any array(reasonably large) of integers, return the maximum difference between any two elements in the array such that the larger element occurs at a higher index than the smaller element. Return -1, if no such pair is found.
Example:
7
2
3
10
2
4
8
1
where the first element is the size of the array(or the number of lines being entered), and the rest are the elements.
Sample output is 8(10-2) for the above.
My code is as follows:
int A[20],size;
scanf("%d",&size);
for(int i=0;i<size;i++){
scanf("%d\n",&A[i]);
}
int diff = A[1]-A[0];
int currsum = diff;
int maxsum = currsum;
for(int i=1; i<size-1; i++)
{
// Calculate current difference for the loop
diff = A[i+1]-A[i];
// Calculate current sum for the loop
if (currsum > 0)
currsum += diff;
else
currsum = diff;
// Update max sum(if needed)
if (currsum > maxsum)
maxsum = currsum;
}
printf("%d",maxsum);
This is a question from Hackerrank, but it runs for only three out of 10 possible testcases. The rest of the cases return a segmentation fault. Any idea would be helpful.

As mentioned in the comments, you've declared A to hold just 20 integers. But the question can send up to 1,000,000 integers. That's the mistake!

Using pointers make this more important. First declare A as pointer of integers, then, read the first element of the array, using this integer you can allocate memory dynamically (malloc() or calloc() function) for your array A. so the size of A will dynamic and you can resize it in function of the first element.

Related

Strange behaviour when finding largest number in Array [duplicate]

This question already has answers here:
Why does the indexing start with zero in 'C'?
(16 answers)
Closed 2 years ago.
Found some very bizarre behaviour when trying to brainstorm a problem:
Purpose of code:
Simple code to find the largest number in an array. I simply store the first index to a variable and compare it to every other index in the list. If another number is larger, that number replaces the number stored in my variable and the process repeats until the end of the list.
#include <stdio.h>
const int SIZE = 8;
int main(void)
{
int arr[] = {7, 3, 9, 14, 1, 27, 14, 2};
int largest;
largest = arr[0];
for (int i = 1; i <= SIZE; i++)
{
if (largest < arr[i])
{
largest = arr[i];
}
}
printf("The largest number in the array is %i\n", largest);
}
Weird behaviour:
This works, sometimes. Other times I get large numbers that give me the impression I've hit an area of memory I shouldn't have. I could understand if this happened every time but because it only happens every 2nd or 3rd time I compile the code I'm bewildered. The code doesn't change and yet the output does
Console Log:
~/pset3/plurality/ $ ./test
The largest number in the array is 1366797536
~/pset3/plurality/ $ ./test
The largest number in the array is 27
~/pset3/plurality/ $ ./test
The largest number in the array is 27
~/pset3/plurality/ $ ./test
The largest number in the array is 1773422672
~/pset3/plurality/ $
My ideas:
The loop somehow hits goes past the end of the array and sees that as the largest number. Again the bizarreness of this is that this only happens 50% of the time
Any ideas would be greatly appreciated.
Your loop is executing one time too many. The loop termination condition i <= SIZE will result in the loop body accessing arr[SIZE], which is outside of the arr array -- remember that C array indices start at 0.
Since the array is stored in the stack frame, your code will be fetching some garbage value from the stack located at the first address beyond the array. This garbage value could be anything, and so could be a large positive value, resulting in what you are seeing.
In C the arrays indices start from 0 to N - 1, with N begin the number of elements of that array, when you do:
for (int i = 1; i <= SIZE; i++)
you are accessing a position out of the allocate memory for that array, therefore you will be reading a random value from memory. Which is considered to be undefined behavior. Hence the reason why:
Again the bizarreness of this is that this only happens 50% of the
time
Sometimes the value that you will be reading from the position outside the array boundaries (i.e., will arr[i] with i = SIZE); will be bigger than the values that you have on the array, other times it will not. Hence, the name undefined behavior.
TLDR: You count i to 8 instead of 7 so you access a value out of bounds of the array. Remove the = sign in the declaration of the for loop.
You are counting from 1...8 in your for loop.
const int SIZE = 8;
…
for (int i = 1; i <= SIZE; i++)
Your Array has 8 values stored so you can access them with arr[0] … arr[7]
If you Access arr[8], which happens in the last Iteration of the for loop since you Count i up to 8 instead of 7 you Access a value out of Bounds, which gives you a kinda random value

Max Sum Contiguous Subarray in C

The problem is to find the max contiguous sub array sum; I am getting 0 as the output and in some case a random number(I checked for going out of array bound but all seems fine).
I saw the similar problems asked in STACK OVERFLOW but most of them was for small input and in other programming language.
here is my code:
int maxSubArray(const int* A, int n1)
{
int i,j,max[n1],L;
for (i=0;i<n1-1;i++)
{
int sum=A[i]+A[i+1];
max[i]=sum;
for(j=i+1;j<n1-1;j++)
{
sum=sum+A[j+1];
if(sum>max[i])
{
max[i]=sum;
}
}
}
for(i=1;i<n1;i++)
{
L=max[0];
if(max[i]>L)
{
L=max[i];
}
}
return(L);
}
Please help me finding what's wrong with my code.
the OP really wants to sum at least 2 entries (not 0 or 1).
The L=max[0] needs to be before the second outer loop (in which we determine which entry is largest).
The second outer loop goes one entry too far, because the last entry is not defined (because of the 2 entries rule)
Here is the pseudocode:
current_sum = 0
best_sum = 0
Iterate through array:
if current sum less than current sum + array[i]
current_sum = current_sum + array[i]
if best sum less than current sum
best_sum = current_sum

Smallest sum of a sequence of numbers in the array. Do not need code [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 7 years ago.
Improve this question
Write a function called smallest_sum_sequence() that accepts an array
of signed integers and the number of items in the array as arguments,
and returns the smallest sum of a sequence of numbers in the array. A
sequence is defined as a single item or multiple items that are in
adjacent memory locations.
This is obviously homework, I do not need anyone to write the code for me just an explanation of what they actually are looking for, as it is worded weirdly in my opinion.
I think what they are wanting is:
Given an array and the total items in the array.
Have the user input a sequence of values for the array ( array[7] -> array[9] )
return smallest sum
Then determine the smallest sum? Is that supposed to be the smallest value or the smallest combination of items? The first sounds too easy and the second doesn't make sense even if you have negatives.
Am looking for any sort of enlightenment.
So a sequence is a set of any number of adjacent numbers in an array. In a set like
[A B C D E]
Any individual could be an answer. Or [A B] could be an answer. Or [A B C]. Or [C D E]. Or even [A B C D E]. But, definitely not [A D E] since A is not adjacent to D in the original set. Easy.
Now you have to write code that will compare the sum of the values in every possible adjacent sequence, in any set of numbers (given the size of that set beforehand).
Edited as the prior answer was wrong!
This is how I understand it. Assume you have an array of signed integers, called A, consisting of, say, <3, 4, 5>. So n = 3, the length of the array.
Your sequence is defined to be a single (or multiple) items in adjacent memory locations. So A[0] and A[1] would be a sequence as they are in adjacent memory locations, but A[0] and A[2] wouldn't be.
You call your function: smallest_sum_sequence(A, n) with A and n as above.
So your sequences are:
+ of length 1) <3>, <4>, <5>
+ of length 2) <3,4>, <4,5>
+ of length 3) <3, 4, 5>
Hence your function should return 3 in this case.
You have to sum each int with the next one and find the min of the sum
You can walk like this
int min = INT_MAX;
for (i = 0; i < len; i++) {
sum = array[i];
min = MIN(min, sum);
for (j = i + 1; j < len ; j++ ) {
sum += array[j];
min = MIN(min, sum);
}
}
With an array of signed integers it is possible that a larger sequence produces a smaller sum than a single number or a pair.
To find out you need to produce all possible sequences:
Start with first number alone, then first and second, then first, second and third.
Then start with second number ...
Then the sum of each sequence.
Return smallest sum (and probably the matching sequence)
Let's look closely at the requirements:
Write a function ... smallest_sum_sequence() that accepts (1) an
array of signed integers and (2) the number of items in the array
as arguments, and (3) returns the smallest sum of a sequence of
numbers in the array.
A sequence is defined as a single item or multiple items ... in
adjacent memory locations.
Taking them one at a time, you know you will write a function that accepts an array of type int and then number of items (won't be negative, so size_t is a good type). Since it must return a smallest sum, the return type of the function can be int as well:
int smallest_sum_sequence (int *a, size_t n)
{
...
return ssum;
}
That is the basic framework for your function. The next issue to address is the smallest sum. Since you are told you are accepting an array of signed values, you must presume that the values within the array can be both negative and positive numbers. You are next told the sum of the smallest sequence can be be derived from a single or multiple adjacent values?
What I interpret this to mean is that you must keep 2 running values. (1) the minimum value in the array; and (2) a sum of the smallest sequences.
In the arguments you get the number of elements in the array providing you with an easy means to iterate over the array itself:
int i = 0;
int min = INT_MAX; /* largest possible minimum number */
int ssum = INT_MAX; /* largest possible smallest sum */
for (i = 0; i < n; i++) {
min = a[i] < min ? a[i] : min;
if (i > 0) {
int tssum = 0; /* temporary smallest sum */
/* test adjacent values {
if adjacent: tssum += a[i]; {
if no longer adjacent {
compare tssum < ssum, if so ssum = tssum;
}
}
} */
}
}
In your first iteration over the array, you have found min the minimum single value and ssum the sum of the smallest sequence. Now all that is left is the return:
return min < ssum ? min : ssum;
That is my impression of what the logic asked for. You may have to adjust the logic of the pseudo-code and you need to figure out how to identify a sequence start/end, but this should at least give you an outline of one way to approach it. Good luck.

Count the number of initialized elements in an array in C

My array is:
int array[100];
If I initialize the first n elements (n < 100) with integers including 0, and the rest is uninitialized, how do I calculate n?
I tried a normal while loop with the following codes:
int i = 0;
int count = 0;
while (a[i++])
count++;
However, the problem with these codes is that it doesn't count the element of value 0 (it takes 0 as FALSE). How do I overcome this problem?
UPDATE: below is the background of this question
I have the following code:
int a[100];
int i;
for (i = 0; i < 100; i++)
scanf("%d", &a[i]);
If I have to input (just an example):
1 0 1 0 1 *
Then the first 5 elements of the array will be: 1 0 1 0 1. The rest will be uninitialized. In this situation, how do I count the number of these initialized elements to get 5?
If you can't simply record how many elements have been initialized, then you need to use a "magic" value like INT_MIN (the largest negative int) to know when an element is not used. Alternatively, instead of storing ints, store something like this:
struct element {
int value;
int flags; // 0 means not used
};
Oh, one more idea: store the count of initialized elements in the first element. This is sort of how malloc() works sometimes. Then you can make the array have 101 elements and pass (array + 1, array[0]) to functions which expect an array of size 100.

find the largest ten numbers in an array in C

I have an array of int (the length of the array can go from 11 to 500) and i need to extract, in another array, the largest ten numbers.
So, my starting code could be this:
arrayNumbers[n]; //array in input with numbers, 11<n<500
int arrayMax[10];
for (int i=0; i<n; i++){
if(arrayNumbers[i] ....
//here, i need the code to save current int in arrayMax correctly
}
//at the end of cycle, i want to have in arrayMax, the ten largest numbers (they haven't to be ordered)
What's the best efficient way to do this in C?
Study maxheap. Maintain a heap of size 10 and ignore all spilling elements. If you face a difficulty please ask.
EDIT:
If number of elements are less than 20, find n-10 smallest elements and rest if the numbers are top 10 numbers.
Visualize a heap here
EDIT2: Based on comment from Sleepy head, I searched and found this (I have not tested). You can find kth largest element (10 in this case) in )(n) time. Now in O(n) time, you can find first 10 elements which are greater than or equal to this kth largest number. Final complexity is linear.
Here is a algo which solves in linear time:
Use the selection algorithm, which effectively find the k-th element in a un-sorted array in linear time. You can either use a variant of quick sort or more robust algorithms.
Get the top k using the pivot got in step 1.
This is my idea:
insert first 10 elements of your arrayNum into arrMax.
Sort those 10 elements arrMax[0] = min , arrMax[9] = max.
then check the remaining elements one by one and insert every possible candidate into it's right position as follow (draft):
int k, r, p;
for (int k = 10; k < n; k++)
{
r = 0;
while(1)
{
if (arrMax[r] > arrNum[k]) break; // position to insert new comer
else if (r == 10) break; // don't exceed length of arrMax
else r++; // iteration
}
if (r != 0) // no need to insert number smaller than all members
{
for (p=0; p<r-1; p++) arrMax[p]=arrMax[p+1]; // shift arrMax to make space for new comer
arrMax[r-1] = arrNum[k]; // insert new comer at it's position
}
} // done!
Sort the array and insert Max 10 elements in another array
you can use the "select" algorithm which finds you the i-th largest number (you can put any number you like instead of i) and then iterate over the array and find the numbers that are bigger than i. in your case i=10 of course..
The following example can help you. it arranges the biggest 10 elements of the original array into arrMax assuming you have all positive numbers in the original array arrNum. Based on this you can work for negative numbers also by initializing all elements of the arrMax with possible smallest number.
Anyway, using a heap of 10 elements is a better solution rather than this one.
void main()
{
int arrNum[500]={1,2,3,21,34,4,5,6,7,87,8,9,10,11,12,13,14,15,16,17,18,19,20};
int arrMax[10]={0};
int i,cur,j,nn=23,pos;
clrscr();
for(cur=0;cur<nn;cur++)
{
for(pos=9;pos>=0;pos--)
if(arrMax[pos]<arrNum[cur])
break;
for(j=1;j<=pos;j++)
arrMax[j-1]=arrMax[j];
if(pos>=0)
arrMax[pos]=arrNum[cur];
}
for(i=0;i<10;i++)
printf("%d ",arrMax[i]);
getch();
}
When improving efficiency of an algorithm, it is often best (and instructive) to start with a naive implementation and improve it. Since in your question you obviously don't even have that, efficiency is perhaps a moot point.
If you start with the simpler question of how to find the largest integer:
Initialise largest_found to INT_MIN
Iterate the array with :
IF value > largest_found THEN largest_found = value
To get the 10 largest, you perform the same algorithm 10 times, but retaining the last_largest and its index from the previous iteration, modify the largest_found test thus:
IF value > largest_found &&
value <= last_largest_found &&
index != last_largest_index
THEN
largest_found = last_largest_found = value
last_largest_index = index
Start with that, then ask yourself (or here) about efficiency.

Resources