I was writing the quickSort()
function to sort an int[]
when I discovered this -well, I don't what should I call it- undefined behaviour
or error
or some kinda thing that I can't understand right now.
// quick sort
#include <iostream>
#include <cstdlib>
#include <ctime>
#include <iomanip>
using namespace std;
// constant
enum {MAX = 10};
// class
class A
{
private:
int arr[MAX];
public:
A() // constructor
{
srand(time(0));
for(int i = 0; i < MAX; i++)
arr[i] = rand() % 100;
}
// accessing array
int get(int i)
{
return arr[i];
}
// quick sort
int Partition(int left, int right);
void quickSort(int left, int right);
void Swap(int&, int&);
};
// member function definition
int A::Partition(int left, int right)
{
int pivot = arr[right], i = left - 1;
for(int j = left; j <= right-1; j++)
{
if(arr[j] < pivot)
{
i++;
Swap(arr[i], arr[j]);
}
}
Swap(arr[i+1], arr[right]);
return i+1;
}
void A::quickSort(int left, int right)
{
if(left < right)
{
int pi = Partition(left, right);
quickSort(left, pi-1);
quickSort(pi+1, right);
}
}
void A::Swap(int& a, int& b)
{
a = a+b;
b = a-b;
a = a-b;
}
// driver
int main(void)
{
A obj1;
//-------Array initialized--------
cout << "Before sorting:" << endl;
for(int i = 0; i < MAX; i++)
cout << setw(4) << obj1.get(i);
//--------Sorting Array-----------
obj1.quickSort(0, MAX-1);
//--------Sorted Array------------
cout << "\nAfter sorting:" << endl;
for(int i = 0; i < MAX; i++)
cout << setw(4) << obj1.get(i);
return 0;
}
The problem is inside the swap()
function. When I am swapping the values using a int temp
variable, values gets swapped and array gets sorted in ascending order.
But when I am swapping the values without using a temporary int
variable, I'm getting 0
s in the sorted array. As shown below:
Before sorting:
89 43 18 98 23 88 52 18 1 25
After sorting:
1 18 0 0 25 43 0 88 89 98
When I debugged the swap()
, the parameters a
and b
were referring to the same address this
.
You are using wrong format to get name of student. change scanf("%d", &name);
to scanf("%s", name);
Also int marks[4]
creates 4 elements. But in for loop you are reading 5 marks. When i=4
marks[i]
is 5th element. So you have to change int marks[4]
to int marks[5]
I think it will be better to define array size as constant value.
#define MARKS_COUNT 5
int main()
{
// ...
int total = 0, i, marks[MARKS_COUNT];
// ...
for(i=0; i<MARKS_COUNT; i++){
scanf("%d", &marks[i]);
}
for(i=0; i<MARKS_COUNT; i++){
total += marks[i];
}
avr=(float)total/MARKS_COUNT;
// ...
}
Also read about format string here http://www.cplusplus.com/reference/cstdio/scanf/
why this is happening?
The array marks[4]
is too small and assigning to marks[4]
is invalid. In scanf("%d", &marks[i]);
when i == 4
you are assigning a value to marks[4]
. The standard says it's undefined behavior access marks[4]
in any way, so from a standard point of view the program has undefined behavior and anything can happen.
I guess most probably your compiler has placed the local variables such that &marks[4] == &name[0]
- the address of element one past the end of marks
array is the same address of the name
array.
Most probably on your system sizeof(int) >= 2
. When scanf
reads 90
from the input, it stores sizeof(int)
bytes into the pointer you have given it. Assuming &marks[4] == &name[0]
, scanf("%d", &marks[4])
on execution becomes scanf("%d", name);
.
Assuming your environment is sane CHAR_BIT = 8
and your environment is little endian, scanf
really stores one byte 90
into the first byte of the pointer and clears the other bytes. So sscanf("90", "%d", &name[0])
would be "semi"-equal to writing sizeof(int)
bytes into name
- one with value 90 and sizeof(int) - 1
bytes with zeros, much like memcpy(&name[0], (char[sizeof(int)]){90,0}, sizeof(int))
.
Strings in C are zero terminated and because the integer 90 is the letter Z
in ascii and zero is the string termination character, when you later do:
printf("%s", name);
The name
actually points to a null terminated string with the first byte 'Z'
and the second byte being the zero terminating character, so it prints just Z
.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.