Bubblesort decreasing size each time - c

This code:
#include <stdio.h>
#define SIZE 10
int main(){
int a[SIZE]={2,6,4,8,10,12,89,68,45,37};
int pass;
int i;
int hold;
int dim=10;
printf("Data items in original order\n");
for(i=0; i<SIZE; i++){
printf("%4d", a[i]);
}
for(pass=1; pass<SIZE; pass++){
for(i=0; i<dim; i++){
if(a[i]>a[i+1]){
hold=a[i];
a[i]=a[i+1];;
a[i+1]=hold;
}
}
dim--;
}
printf("\nData items in ascending order\n");
for(i=0; i<SIZE; i++){
printf("%4d", a[i]);
}
printf("\n");
return 0;
}
gives me this error:
Data items in original order
2 6 4 8 10 12 89 68 45 37
Data items in ascending order
2 4 6 8 10-98850560 12 37 45 68
*** stack smashing detected ***: ./prog terminated
Why? I don't understand. Please explain it to me. Thank you very much. I just don't get it. I don't understand. Please help me. I don't know what to do. Please.

The problem is with this line:
if(a[i]>a[i+1])
i can go upto dim-1 and dim is 10. So when i becomes 9, the above expression becomes
if(a[9]>a[10])
You will be accessing the 11th element of an array which contains only 10 elements and thus you will access an out-of-bounds memory address. This is undefined behaviour.
From wiki:
The behavior of some programming languages—most famously C and C++—is undefined in some cases. In the standards for these languages the semantics of certain operations is described as undefined. These cases typically represent unambiguous bugs in the code, for example indexing an array outside of its bounds.

stack smashing detected means there is a buffer overflow in the stack, you basically went out of the bound of your array.
int dim=10; dim is 10
for(pass=1; pass<SIZE; pass++){ <<< First loop, dim is still 10
for(i=0; i<dim; i++){ <<< i < 10
if(a[i]>a[i+1]){ <<< Last loop : i=9
hold=a[i];
a[i]=a[i+1];;
a[i+1]=hold;
}
}
dim--;
}
i=9 a[i+1] => a[10] which is out of bound
Hope that helps~~

In statement : if(a[i]>a[i+1]) when i = 9 (max 9 in this for loop), that time you are comparing a[9]>a[10] but you defined array up to a[9].
Modify that for loop as:
for(i=0; i<dim-1; i++)
if(a[i]>a[i+1])

Related

Really don't get why my array doesn't sort ascending but descending

I'm a newbie. Don't really get why it's in descending order and not ascending, since I check each element of array with all other elements and if the former is greater, it becomes the latter, and so on, so the element should go slowly right in the order, but what happens is the opposite.
#include <stdio.h>
void main(void){
unsigned int array[7] = {3,1,6,9,0,44,4};
for (unsigned int i=0; i<=6; ++i){
for (unsigned int j=0; j<=6; ++j){
if (array[i] > array[j]){
int hold = array[j];
array[j] = array[i];
array[i] = hold;
}
}
}
for (unsigned int i=0; i<=6; ++i){
printf("%4d", array[i]);
}
}
Output:
44 9 6 4 3 1
I know that replacing ">" with "<" I have it in ascendent order, but I don't get why.
Edit: following the answers I received, if I replace (in the inner loop) that 0 with "i+1", it works. I'm gonna try to understand better why.
You have attempted to implement a Selection Sort. The code is mostly right, but there is a logical flaw in the way you have structured your loops, and in particular in the range covered by your inner loop. Run your code in a debugger to see what's going on, or try to explain in detail to your rubber duck / pet dog / computer mouse what the code is doing and why.

What does this mean and how do I rectify it *** stack smashing detected ***: ./array1output terminated

This is the code. Why am I facing this error and what source of information should I refer so as to rectify such errors so that I get to know 'If I do this that way, I will get 'x' error'
#include<stdio.h>
void main()
{
int i,avg,sum;
int marks[30]; // Array declaration
for(i=0;i<31;i++)
{
printf("Enter Marks:");
scanf("%d",&marks[i]); // Stores data in Array
}
for(i=0;i<31;i++)
sum=sum+marks[i];
avg=sum/30;
printf("Average marks of student \t %d",avg);
}
Whenever you declare a variable in a function it allocates memory on the stack. The stack is a reserved memory area for doing temporary data manipulation within the function. Now in your code you declared 3 ints and one array of ints with 30 slots. In your for loop you are putting 31 ints into 30 slots; from 0 thru 30 are 31 numbers. The last number is being put beyond the 30th slot and therefore "smashing" into the next spot on the stack, in other words overwriting it. The solution would be to change you for loop to for(i=0;i<30;i++).
You have declared an int type array as [30] and have tried to assign 31 values to it. Please note that the array starts from 0. So the for loop should be as mentioned below.
for(i=0;i<30;i++)
Hence the issue, Please change the for loop and rest are all fine in your code. Thank you. :)
#include<stdio.h>
void main()
{
int i, avg, sum=0;
int marks[30]; // Array declaration
for (i = 0; i<30; i++)
{
printf("Enter Marks:");
scanf("%d", &marks[i]); // Stores data in Array
}
for (i = 0; i<30; i++)
sum = sum + marks[i];
avg = sum / 30;
printf("Average marks of student \t %d", avg);
}

Why is this code outOfBound?

Here is a problem I met the other day in a interview, would someone tell me the "truth" behind this "simple" code?
#include<stdio.h>
int main()
{
int a[]={1,2,3};
for(int i=0; i<=3; i++){
a[i]=0;
printf("%d\n", i);
}
return 0;
}
Everything will be right if <= is replaced by < as it is causing array out of bound index error and will print value
0
1
2
3
although the value of the array content will be 0 every time
The loop variable i takes on values 0, 1, 2, and 3. Unfortunately, 3 is an out-of-bounds index for array a, which only has length 3 (legal indices 0, 1, and 2). To avoid an out-of-bounds array access, the loop control should be
for(int i=0; i<3; i++){
Note the use of < instead of <=. As an interview question, the goal was to test whether you noticed this very common kind of off-by-one error.

*the counter* to reverse an array using pointers doesn't work

#include<stdio.h>
int main() {
int i;
int vector[5]={6,17,28,39,410},*r; //variables declaration
r=(int*)&vector; //pointer declaration
for (i = 0; i<5;i++){ //print the array in using a loop
printf("%d ",vector[i]);
}
printf("\n\n");
for(i=0;i<5;i++){ //print the array in reverse order using a loop
vector[i] = *(r+4-i); //it should be from the last to the first but it prints it
printf("%d ",vector[i]); //differently, see below
}
return 0;}
It should be:
6 17 28 39 410
410 39 28 17 6
but it results in:
6 17 28 39 410
410 39 28 39 410
the last two should be 17 6
You are overwriting the data you're trying to read, before reading it.
Just write out the steps your code is taking manually, and you'll see it.
To do reversal in-place, you must swap values around, to avoid overwriting.
Also note that the name of an array evaluates to a pointer to the first argument, in the proper context. So this:
r=(int*)&vector;
is much better written as just:
r = vector;
You should really avoid casts, and your cast is completely unnecessary.
try this:
#include<stdio.h>
int main() {
int i;
int vector[5]={6,17,28,39,410},*r; //variables declaration
r=(int*)&vector; //pointer declaration
for (i = 0; i<5;i++){ //print the array in using a loop
printf("%d ",vector[i]);
}
printf("\n\n");
for(i=0;i<5;i++){ //print the array in reverse order using a loop
//it should be from the last to the first but it prints it
printf("%d ",*(r+4-i)); //differently, see below
}
return ( 0 );
}
In your code you are changing the first two values. So first two steps Your array
will be like this.
410 39 28 39 410
After that loop continues it will get that replaced value. You can store the replaced value in the another array.
for(i=0,j=4;i<j;i++,j--){
temp=vector[i]; // storing the value in temporary variable
vector[i] = r[j];
r[j]=temp; // assigning the value .
}
for ( i=0; i < 5 ; i ++ )
printf("%d\n",vector[i]);

How could it be possible to read and write past the array

Output of the program:
#include <stdio.h>
int main()
{
int size;
printf("Enter the size of array: ");
scanf("%d",&size);
int b[size],i = 0;
printf("Enter %d integers to be printed: ",size);
while(i++ < size)
{
scanf("%d",&b[i]);
printf("%d %d\n", i, b[i]);
}
return 0;
}
for size = 5 and input numbers :
0 1 2 3 4
is
1 0
2 1
3 2
4 3
5 4
where first column is for i and second for elements of array b.
It is clear that i in the loop while(i++ < size) { incremented to 1 before entering the loop. This loop should have to store/print the value at/of b[1], b[2], b[3], b[4] but not b[5] as loop will terminate at i = 5.
How this code is printing the value of b[5]?
I have tested it for different array size and it is not printing any garbage value.
By reading and writing past the array, your program invokes undefined behavior. It doesn't mean that it has to crash or print garbage values, it can pretend working fine. Apparently, that's what is happening in this case.
In your loop, the condition i < size is checked before i is incremented. But, i is incremented before entering the body of the loop and not after it, so it is possible to access b[5] in this case, as i would be incremented after checking i < size with i=4. You do not want that, as this causes undefined program behavior.
If you try to access an element in the array which does not exist, e.g. array[size], you are accessing the next spot in the memory right after the array. In this case you are lucky, but if this meant you were accessing a part of the memory where your program isn't allowed to do so, you'd get a segmentation fault.
you could use a for cycle instead of a while so instead of while(i++<size)you could use for(i = 0; i < size; i++) that should solve your problem my friend :)

Resources