Reputation: 83
I am trying to learn C++ by firstly going through the low level details before I start using abstractions such as std::copy or memcpy. Currently I am stuck in trying to figure out why this code is never assigning into "sortedArray" variable, when looking with debugger I dereference the value from "data" correctly but it is never assigned to "sortedArray". I see value such as "-842150451" instead of "14" for first value. Can you please help me figure out what I am doing wrong ? And any other issues there may be that I do not see or advice would be greatly appreciated !
void swap(int* bigger, int* smaller){
*bigger += *smaller;
*smaller = *bigger - *smaller;
*bigger = *bigger - *smaller;
}
int* bubbleSort(int *data, int size){
bool swapped = true;
int *sortedArray = (int*)malloc(size*sizeof(int));
for (int i = 0; i < size;i++){
*(sortedArray++) = *(data++);
}
while (swapped){
swapped = false;
for (int i = 1; i <= size - 1; i++){
if (sortedArray[i - 1] > sortedArray[i]){
swap(&sortedArray[i - 1], &sortedArray[i]);
swapped = true;
}
}
size--;
}
return sortedArray;
}
Upvotes: 0
Views: 2858
Reputation: 5290
You first pointer sortedArray
points to some allocated memory.
Then in the first for loop you increment the pointer. not it doesn't point to that memory anymore.
Simply use a temporary pointer for the memory copy.
int* t = sortedArray ;
And now use t
in your for loop which copies the data.
Instead of the temporary variable, you can rather count the number of times you called sortedArray++
in your for loop.
If you take a look: for (int i = 0; i < size;i++)
you will see that the loop took exactly size
number of iterations.
Just subtract size from the pointer after the loop and you point back to your allocated memory.
sortedArray -= size ;
Upvotes: 1
Reputation: 141544
Change
*(sortedArray++) = *(data++);
to
sortedArray[i] = data[i];
You need to leave intact the pointer to the block of memory you allocated, so you can use it (and free it) later.
Note, there is nothing to be gained by using the *(x+y)
syntax instead of x[y]
, they are equivalent but the latter is easier to read.
In C++ you should not use malloc
. Instead use new int[size]
. For int
there is no difference other than reduced risk of making a typo, however for non-trivial types malloc
will not construct them correctly.
Upvotes: 2
Reputation: 4924
*(sortedArray++) = *(data++);
modifies the pointer so it no longer points to the start of the allocated memory. So, later on sortedArray[i]
is whatever happens to be in memory past the array, and accessing it is undefined behavior.
If you must use pointers, a quick fix is to use a temporary one, like:
int *sortedArray = (int*)malloc(size*sizeof(int));
int* s = sortedArray;
for (int i = 0; i < size;i++){
*s++ = *data++;
}
Another way would be:
int *sortedArray = (int*)malloc(size*sizeof(int));
for (int i = 0; i < size;i++){
sortedArray[i] = data[i];
}
But, the best way would be to use standard containers and algorithms, like vector
and sort
.
Here's a demo of the first fix in action.
Upvotes: 7
Reputation: 76240
That is not C++ at all. You can write generic code that takes a begin
iterator and an end
iterator in order for it to work with any kind of container that supports such semantic.
template<typename IT>
void bubble_sort(IT begin, IT end) {
while (true) {
bool swapped = false;
for (IT i = begin; i != end-1; i = i+1) {
if (*i > *(i+1)) {
std::iter_swap(i, i+1);
swapped = true;
}
}
if (swapped == false) return;
}
}
Where std::iter_swap
is like std::swap
but works on iterators. You can see iterators as a pair of pointers to the beginning and (past the) end of a container.
Upvotes: 1