Swapping pointers [duplicate] - c++

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Swapping objects using pointers
I know how to do swapping using pointers, but then, if I try a different approach like this:
/* Pointers */
#include <stdio.h>
int main ()
{
int a=4,b=6;
swap(&a,&b);
printf("A is %d, and B is %d\n",a,b);
return 0;
}
int swap(int *a, int *b)
{
int *temp;
temp = a;
a = b;
b = temp;
return 0;
}
It doesn't work. Basically the swap function is changing the address, like 'a' now has the address of 'b', and vice-versa.. If I print out the values in swap function, it gives swapped values, but it is not reflected in main function. Can any one tell me why?

Because
the swap function is changing the address, like 'a' now has the address of 'b', and vice-versa
is not true. It doesn't change their addresses (that would make absolutely no sense whatsoever). The function changes the values of the pointers - those pointers are copies of the addresses, and these pointers, since they're function arguments, are local to the function. What you have to do is:
int swap(int *a, int *b)
{
int temp;
temp = *a;
*a = *b;
*b = temp;
return 0;
}
Or you can use references (only in C++), like this:
int swap(int &a, int &b)
{
int temp;
temp = a;
a = b;
b = temp;
return 0;
}
and call it without the addressof operator:
int a = 4, b = 6;
swap(a, b);
However, if this is for an actual implementation, and not a "write a swap function"-style homework, then you should use the std::swap() function from <algorithm>.

If you simply take them as inout using the standard method, you will receive a COPY of the variable, not the actual variable. However when you pass a *variable you give it a variable that points to the actual variable. You can then set the memory location using swap because a copy of a memory location is still the same.
So try this code for your function:
int swap(int *a, int *b)
{
int tmp;
tmp = *a;
*a = *b;
*b = tmp;
return 0;
}

'a' and 'b' in swap aren't the 'a' and 'b' in main. Within swap, these are pointers. If you want to swap the values pointed by a,b, you need:
int swap( int* pa, int *pb )
{
int temp;
temp = *pa;
*pa = *pb;
*pb = temp;
return 0;
}
note I'm using more appropriate variable names. Also, you need to allocate temp (vs allocating pointer to temp).

You can try using:
int swap(int*& a, int*& b)
{
int *temp;
temp = a;
a = b;
b = temp;
return 0;
}
Note that stack addresses cannot be moved so you'll need a different main:
int main ()
{
int a=4,b=6;
int *A = &a;
int *B = &b;
swap(A, B);
printf("A is %d, and B is %d\n",*A, *B);
return 0;
}

Related

freeing the same memory with distructors

I try to free the memory correctly after the program ends, but I always encounter a problem.
In my code I want to have an array of all the numbers that I allow in my program, and have objects A and B (or more) that each one have some of the numbers that I allowed.
In the end I want to delete 'a' and 'b' only after "ints" getting out of the scope. But A and B calls their distructors to delete some of ints variables.
#define MAX_LEN 255
class IntArray
{
public:
int len;
void add(int* n) {
arr[len] = n; len++;
}
IntArray() : arr(new int* [MAX_LEN]), len(0) {}
~IntArray() {
for (int i = 0; i < len; i++)
delete arr[i];
delete[] arr;
}
private:
int** arr;
};
class Object
{
public:
void add(int* n) {
myIntArr.add(n);
}
private:
IntArray myIntArr;
};
int main(void)
{
int* a = new int(5);
int* b = new int(6);
IntArray ints;
ints.add(a);
ints.add(b);
Object A;
A.add(a);
Object B;
B.add(b);
return 0;
}
If you want to share dynamically allocated ints between multiple objects, use std::shared_ptr<int>.
Also, rather than writing a dynamic array type yourself, use std::vector to do it (correctly) for you.
using int_ptr = std::shared_ptr<int>;
class IntArray
{
public:
void add(int_ptr n) {
arr.push_back(n);
}
private:
std::vector<int_ptr> arr
};
class Object
{
public:
void add(int_ptr n) {
myIntArr.add(n);
}
private:
IntArray myIntArr;
};
int main(void)
{
int_ptr a = std::make_shared<int>(5);
int_ptr b = std::make_shared<int>(6);
IntArray ints;
ints.add(a);
ints.add(b);
Object A;
A.add(a);
Object B;
B.add(b);
return 0;
}
If you just want to have a copyable array of int, use std::vector<int>.
You're deleting a and b twice.
You should only delete something returned by new and exactly once.
But you add them both to IntArray ints; and then one each to Objects A and B and their destructors delete them also. Destructors are called in reverse order to it's when ints is destructed you'll be deleting them again - that's "Undefined Behaviour" but normally a catastrophic failure (crash) either immediately or later during executon.
The shortest fix is:
int* a = new int(5);
int* b = new int(6);
int *ac = new int(*a);//copy of *a
int *ab = new int(*b);//copy of *b
IntArray ints;
ints.add(a);
ints.add(b);
Object A;
A.add(ac);
Object B;
B.add(bc);
But it's not clear what our intention is. IntArray isn't an array of int as it stands, it's an array of pointers to int (which have been allocated by new).
My 'fix' will mean if you modify a (e.g. *a=20) you won't modify the copy (ac) added to the Object A.

accessing data members of nested struct and passing struct to function C++

I have a simple problem but I need to understand the concept behind it.
How to access data members of a 1st struct by instantiating it as pointer in 2nd struct.
If I make data members of 1st struct as pointer then how to print out there values by accessing them e.g.
struct temp
{
int a =5;
float b = 6.0;
i = &a;
f = &b;
int *i;
float *f;
};
I am working on a complex code so I need to understand the logic behind it as how it works in-terms of memory and logic.
Thanks a lot for your time in advance.
#include <iostream>
using namespace std;
struct temp {
int i=5;
float f=6.0;
};
struct qlt {
temp *d;
};
int sum (qlt *s)
{
int a = s->d->i;
// std::cout<<a;
}
int main() {
qlt x;
//int b = ;
std::cout <<sum(&x);
return 0;
}
qlt x;
This creates a qlt allright, but not the d inside it. So you have a dangling pointer (since it's also left uninitialized).
qlt x;
temp b;
x.d = &b;
this would be a C-style solution. C++ has way better ways to do it.
Forget all sort of pointers at this moment and use STL.

How to return a pointer to an array for use in a separate function [duplicate]

How can I return an array from a method, and how must I declare it?
int[] test(void); // ??
int* test();
but it would be "more C++" to use vectors:
std::vector< int > test();
EDIT
I'll clarify some point. Since you mentioned C++, I'll go with new[] and delete[] operators, but it's the same with malloc/free.
In the first case, you'll write something like:
int* test() {
return new int[size_needed];
}
but it's not a nice idea because your function's client doesn't really know the size of the array you are returning, although the client can safely deallocate it with a call to delete[].
int* theArray = test();
for (size_t i; i < ???; ++i) { // I don't know what is the array size!
// ...
}
delete[] theArray; // ok.
A better signature would be this one:
int* test(size_t& arraySize) {
array_size = 10;
return new int[array_size];
}
And your client code would now be:
size_t theSize = 0;
int* theArray = test(theSize);
for (size_t i; i < theSize; ++i) { // now I can safely iterate the array
// ...
}
delete[] theArray; // still ok.
Since this is C++, std::vector<T> is a widely-used solution:
std::vector<int> test() {
std::vector<int> vector(10);
return vector;
}
Now you don't have to call delete[], since it will be handled by the object, and you can safely iterate it with:
std::vector<int> v = test();
std::vector<int>::iterator it = v.begin();
for (; it != v.end(); ++it) {
// do your things
}
which is easier and safer.
how can i return a array in a c++ method and how must i declare it? int[] test(void); ??
This sounds like a simple question, but in C++ you have quite a few options. Firstly, you should prefer...
std::vector<>, which grows dynamically to however many elements you encounter at runtime, or
std::array<> (introduced with C++11), which always stores a number of elements specified at compile time,
...as they manage memory for you, ensuring correct behaviour and simplifying things considerably:
std::vector<int> fn()
{
std::vector<int> x;
x.push_back(10);
return x;
}
std::array<int, 2> fn2() // C++11
{
return {3, 4};
}
void caller()
{
std::vector<int> a = fn();
const std::vector<int>& b = fn(); // extend lifetime but read-only
// b valid until scope exit/return
std::array<int, 2> c = fn2();
const std::array<int, 2>& d = fn2();
}
The practice of creating a const reference to the returned data can sometimes avoid a copy, but normally you can just rely on Return Value Optimisation, or - for vector but not array - move semantics (introduced with C++11).
If you really want to use an inbuilt array (as distinct from the Standard library class called array mentioned above), one way is for the caller to reserve space and tell the function to use it:
void fn(int x[], int n)
{
for (int i = 0; i < n; ++i)
x[i] = n;
}
void caller()
{
// local space on the stack - destroyed when caller() returns
int x[10];
fn(x, sizeof x / sizeof x[0]);
// or, use the heap, lives until delete[](p) called...
int* p = new int[10];
fn(p, 10);
}
Another option is to wrap the array in a structure, which - unlike raw arrays - are legal to return by value from a function:
struct X
{
int x[10];
};
X fn()
{
X x;
x.x[0] = 10;
// ...
return x;
}
void caller()
{
X x = fn();
}
Starting with the above, if you're stuck using C++03 you might want to generalise it into something closer to the C++11 std::array:
template <typename T, size_t N>
struct array
{
T& operator[](size_t n) { return x[n]; }
const T& operator[](size_t n) const { return x[n]; }
size_t size() const { return N; }
// iterators, constructors etc....
private:
T x[N];
};
Another option is to have the called function allocate memory on the heap:
int* fn()
{
int* p = new int[2];
p[0] = 0;
p[1] = 1;
return p;
}
void caller()
{
int* p = fn();
// use p...
delete[] p;
}
To help simplify the management of heap objects, many C++ programmers use "smart pointers" that ensure deletion when the pointer(s) to the object leave their scopes. With C++11:
std::shared_ptr<int> p(new int[2], [](int* p) { delete[] p; } );
std::unique_ptr<int[]> p(new int[3]);
If you're stuck on C++03, the best option is to see if the boost library is available on your machine: it provides boost::shared_array.
Yet another option is to have some static memory reserved by fn(), though this is NOT THREAD SAFE, and means each call to fn() overwrites the data seen by anyone keeping pointers from previous calls. That said, it can be convenient (and fast) for simple single-threaded code.
int* fn(int n)
{
static int x[2]; // clobbered by each call to fn()
x[0] = n;
x[1] = n + 1;
return x; // every call to fn() returns a pointer to the same static x memory
}
void caller()
{
int* p = fn(3);
// use p, hoping no other thread calls fn() meanwhile and clobbers the values...
// no clean up necessary...
}
It is not possible to return an array from a C++ function. 8.3.5[dcl.fct]/6:
Functions shall not have a return type of type array or function[...]
Most commonly chosen alternatives are to return a value of class type where that class contains an array, e.g.
struct ArrayHolder
{
int array[10];
};
ArrayHolder test();
Or to return a pointer to the first element of a statically or dynamically allocated array, the documentation must indicate to the user whether he needs to (and if so how he should) deallocate the array that the returned pointer points to.
E.g.
int* test2()
{
return new int[10];
}
int* test3()
{
static int array[10];
return array;
}
While it is possible to return a reference or a pointer to an array, it's exceedingly rare as it is a more complex syntax with no practical advantage over any of the above methods.
int (&test4())[10]
{
static int array[10];
return array;
}
int (*test5())[10]
{
static int array[10];
return &array;
}
Well if you want to return your array from a function you must make sure that the values are not stored on the stack as they will be gone when you leave the function.
So either make your array static or allocate the memory (or pass it in but your initial attempt is with a void parameter). For your method I would define it like this:
int *gnabber(){
static int foo[] = {1,2,3}
return foo;
}
"how can i return a array in a c++ method and how must i declare it?
int[] test(void); ??"
template <class X>
class Array
{
X *m_data;
int m_size;
public:
// there constructor, destructor, some methods
int Get(X* &_null_pointer)
{
if(!_null_pointer)
{
_null_pointer = new X [m_size];
memcpy(_null_pointer, m_data, m_size * sizeof(X));
return m_size;
}
return 0;
}
};
just for int
class IntArray
{
int *m_data;
int m_size;
public:
// there constructor, destructor, some methods
int Get(int* &_null_pointer)
{
if(!_null_pointer)
{
_null_pointer = new int [m_size];
memcpy(_null_pointer, m_data, m_size * sizeof(int));
return m_size;
}
return 0;
}
};
example
Array<float> array;
float *n_data = NULL;
int data_size;
if(data_size = array.Get(n_data))
{ // work with array }
delete [] n_data;
example for int
IntArray array;
int *n_data = NULL;
int data_size;
if(data_size = array.Get(n_data))
{ // work with array }
delete [] n_data;

How can I return this 2d array? [duplicate]

How can I return an array from a method, and how must I declare it?
int[] test(void); // ??
int* test();
but it would be "more C++" to use vectors:
std::vector< int > test();
EDIT
I'll clarify some point. Since you mentioned C++, I'll go with new[] and delete[] operators, but it's the same with malloc/free.
In the first case, you'll write something like:
int* test() {
return new int[size_needed];
}
but it's not a nice idea because your function's client doesn't really know the size of the array you are returning, although the client can safely deallocate it with a call to delete[].
int* theArray = test();
for (size_t i; i < ???; ++i) { // I don't know what is the array size!
// ...
}
delete[] theArray; // ok.
A better signature would be this one:
int* test(size_t& arraySize) {
array_size = 10;
return new int[array_size];
}
And your client code would now be:
size_t theSize = 0;
int* theArray = test(theSize);
for (size_t i; i < theSize; ++i) { // now I can safely iterate the array
// ...
}
delete[] theArray; // still ok.
Since this is C++, std::vector<T> is a widely-used solution:
std::vector<int> test() {
std::vector<int> vector(10);
return vector;
}
Now you don't have to call delete[], since it will be handled by the object, and you can safely iterate it with:
std::vector<int> v = test();
std::vector<int>::iterator it = v.begin();
for (; it != v.end(); ++it) {
// do your things
}
which is easier and safer.
how can i return a array in a c++ method and how must i declare it? int[] test(void); ??
This sounds like a simple question, but in C++ you have quite a few options. Firstly, you should prefer...
std::vector<>, which grows dynamically to however many elements you encounter at runtime, or
std::array<> (introduced with C++11), which always stores a number of elements specified at compile time,
...as they manage memory for you, ensuring correct behaviour and simplifying things considerably:
std::vector<int> fn()
{
std::vector<int> x;
x.push_back(10);
return x;
}
std::array<int, 2> fn2() // C++11
{
return {3, 4};
}
void caller()
{
std::vector<int> a = fn();
const std::vector<int>& b = fn(); // extend lifetime but read-only
// b valid until scope exit/return
std::array<int, 2> c = fn2();
const std::array<int, 2>& d = fn2();
}
The practice of creating a const reference to the returned data can sometimes avoid a copy, but normally you can just rely on Return Value Optimisation, or - for vector but not array - move semantics (introduced with C++11).
If you really want to use an inbuilt array (as distinct from the Standard library class called array mentioned above), one way is for the caller to reserve space and tell the function to use it:
void fn(int x[], int n)
{
for (int i = 0; i < n; ++i)
x[i] = n;
}
void caller()
{
// local space on the stack - destroyed when caller() returns
int x[10];
fn(x, sizeof x / sizeof x[0]);
// or, use the heap, lives until delete[](p) called...
int* p = new int[10];
fn(p, 10);
}
Another option is to wrap the array in a structure, which - unlike raw arrays - are legal to return by value from a function:
struct X
{
int x[10];
};
X fn()
{
X x;
x.x[0] = 10;
// ...
return x;
}
void caller()
{
X x = fn();
}
Starting with the above, if you're stuck using C++03 you might want to generalise it into something closer to the C++11 std::array:
template <typename T, size_t N>
struct array
{
T& operator[](size_t n) { return x[n]; }
const T& operator[](size_t n) const { return x[n]; }
size_t size() const { return N; }
// iterators, constructors etc....
private:
T x[N];
};
Another option is to have the called function allocate memory on the heap:
int* fn()
{
int* p = new int[2];
p[0] = 0;
p[1] = 1;
return p;
}
void caller()
{
int* p = fn();
// use p...
delete[] p;
}
To help simplify the management of heap objects, many C++ programmers use "smart pointers" that ensure deletion when the pointer(s) to the object leave their scopes. With C++11:
std::shared_ptr<int> p(new int[2], [](int* p) { delete[] p; } );
std::unique_ptr<int[]> p(new int[3]);
If you're stuck on C++03, the best option is to see if the boost library is available on your machine: it provides boost::shared_array.
Yet another option is to have some static memory reserved by fn(), though this is NOT THREAD SAFE, and means each call to fn() overwrites the data seen by anyone keeping pointers from previous calls. That said, it can be convenient (and fast) for simple single-threaded code.
int* fn(int n)
{
static int x[2]; // clobbered by each call to fn()
x[0] = n;
x[1] = n + 1;
return x; // every call to fn() returns a pointer to the same static x memory
}
void caller()
{
int* p = fn(3);
// use p, hoping no other thread calls fn() meanwhile and clobbers the values...
// no clean up necessary...
}
It is not possible to return an array from a C++ function. 8.3.5[dcl.fct]/6:
Functions shall not have a return type of type array or function[...]
Most commonly chosen alternatives are to return a value of class type where that class contains an array, e.g.
struct ArrayHolder
{
int array[10];
};
ArrayHolder test();
Or to return a pointer to the first element of a statically or dynamically allocated array, the documentation must indicate to the user whether he needs to (and if so how he should) deallocate the array that the returned pointer points to.
E.g.
int* test2()
{
return new int[10];
}
int* test3()
{
static int array[10];
return array;
}
While it is possible to return a reference or a pointer to an array, it's exceedingly rare as it is a more complex syntax with no practical advantage over any of the above methods.
int (&test4())[10]
{
static int array[10];
return array;
}
int (*test5())[10]
{
static int array[10];
return &array;
}
Well if you want to return your array from a function you must make sure that the values are not stored on the stack as they will be gone when you leave the function.
So either make your array static or allocate the memory (or pass it in but your initial attempt is with a void parameter). For your method I would define it like this:
int *gnabber(){
static int foo[] = {1,2,3}
return foo;
}
"how can i return a array in a c++ method and how must i declare it?
int[] test(void); ??"
template <class X>
class Array
{
X *m_data;
int m_size;
public:
// there constructor, destructor, some methods
int Get(X* &_null_pointer)
{
if(!_null_pointer)
{
_null_pointer = new X [m_size];
memcpy(_null_pointer, m_data, m_size * sizeof(X));
return m_size;
}
return 0;
}
};
just for int
class IntArray
{
int *m_data;
int m_size;
public:
// there constructor, destructor, some methods
int Get(int* &_null_pointer)
{
if(!_null_pointer)
{
_null_pointer = new int [m_size];
memcpy(_null_pointer, m_data, m_size * sizeof(int));
return m_size;
}
return 0;
}
};
example
Array<float> array;
float *n_data = NULL;
int data_size;
if(data_size = array.Get(n_data))
{ // work with array }
delete [] n_data;
example for int
IntArray array;
int *n_data = NULL;
int data_size;
if(data_size = array.Get(n_data))
{ // work with array }
delete [] n_data;

C++, what is the purpose of argument type (void*&)?

I am trying to understand a certain code where I found something hard to understand for me.
void BPlusTree::GetKey(int key, void*& keyloc) const {
keyloc = keys + key * attrLength;
return 0;
}
This function calculates the location (memory address) of the key value and store it at keyloc variable.
void*& means the reference for a void pointer.
And here reference is used to reflect the changed value of keyloc to the outer function which called `GetKey.
Am I right till now?
So I thought that, in the main function, when it calls GetKey function. It needs to pass (void*) not the (void*&).
int main() {
.....
int currPos = 0;
char* key = NULL;
int result = currNode->GetKey(currPos, (void*&) key);
}
Why is (void*&) used instead of (void*) here?
Thank you.
// And I added here example code...
#include <regex>
#include <iostream>
#include <stdlib.h>
using namespace std;
#include <stdio.h>
void foo(int &a, int &b) {
a = 10;
b = 20;
}
void foo2(int* &c, int* &d) {
*c = 10;
*d = 20;
}
void foo3(void* &c, void* &d) {
*(int*)c = 10;
*(int*)d = 20;
}
int main(void) {
int a = 0;
int b = 0;
int* c = new int;
int* d = new int;
void* e = malloc(sizeof(int));
void* f = malloc(sizeof(int));
foo(a, b);
printf("A is %d and B is %d\n", a, b);
foo2(c, d);
printf("C is %d and D is %d\n", *c, *d);
foo3((void*&)c,(void*&) d); // It works fine
printf("C is %d and D is %d\n", *c, *d);
foo3((void*)c,(void*) d); // But it does not work
printf("C is %d and D is %d\n", *c, *d);
}
Is the (void*) problematic one?? :D
Yes, you're pretty much right in what you do understand. For the last bit, perhaps it'll be easier to use a pointer instead of a reference in explaining...
You could have had
void BPlusTree::GetKey(int key, void** keyloc) const { ... };
and a caller
char* key = NULL;
int result = currNode->GetKey(currPos, (void**) &key);
Here, it should be obvious why you cannot use &(void*) key: (void*) key is an rvalue, and you cannot take its address. It'd be like taking the address of (key + 0). Sure, key + 0 is always just key, but the mere fact that you have an addition there means you're looking at a copy of the pointer value, not the original pointer object.
When dealing with references, there is not an explicit "address of" operation like there is with pointers, but the problem is the same. GetKey(currPos, (void*) key) doesn't work because (void*) key is an rvalue, not an lvalue. (void*&) key casts key to "reference to void*", and pretty much means *(void**) &key. It is done to pretend that key was actually defined as void*.
Note: this is generally considered very bad practice. key would be better actually defined as void*, and then no cast is required to call GetKey.