Printing the value of an int Pointer - c++

I have been working on this and I can't seem to get this working properly. I am returning a pointer list's last value, and I would like to print it, but It is printing a very random number. I assuming that this is the memory address of the pointer, but when I dereference it, my output still does the same thing.
My Pointerlist is a list of pointers, like: list<int*> pointerList
For example, this is my method returning :
int* end() { return (pointerList.back()); }
An this is how I am calling it.
int* totry = ca.end();
cout << *totry;
This is printing the Memory Adress and not the value. Does anyone have any Ideas how to solve this?
Thanks in advance!
EDIT:
Here is what the int pointers are pointing to:
I have a list of values such as [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15]
And I have a list of pointers that points to different parts of that list like the following:
[0,4,8,12]
I have the Code: int* end() { return (pointerList.back()); } in my Header file, and the call in my .cpp file:
int* totry = ca.end();
cout << *totry;
This is how I declare my pointerlist
class ptrList
{
public:
std::list<value_type> listOfValues;
std::list<*int> pointerlist;
I fill my list pointers inside an "add" function, and I do it like this:
int lstsqrt = 4;
for (int a = 1; a < lstsqrt; a++)
{
int endptr = a + (int)lstsqrt;
pointerlist.push_back((&*listOfValues.begin() + endptr)); //( (lstsqrt - 1) + a) );
}
And this is my end() method
int* end() {return (pointerlist.back());}
And this is then passed to my toTry Variable.

One problem is likely to be this line:
pointerlist.push_back((&*listOfValues.begin() + endptr));
Your listOfValues is a std::list, and therefore its values are not stored in a contiguous block of memory. So you're getting an iterator to the first element with listOfValues.begin(), dereferencing the iterator with *, taking the address of that with & to get an int*, then adding some value which points somewhere off into memory that you don't know what it is.
Try doing this instead:
pointerlist.push_back((&*(listOfValues.begin() + endptr)));
where you add endptr to the iterator (to advance it along the list), then dereference and take the address. Actually you may need to use advance instead of +.

Related

C++ quicksort with const unsigned** input pointers

I am currently struggling with Pointers in C++, especially with the input of following function:
/*
... there is an immutable array a of unsigned integers that we are not allowed to change
In order to sort this array, a second array b containing pointers to the individual
elements in a is created. We then sort the poiners in b based on the values of the pointed-to elements in a.
(d) implement the quicksort function which sorts an array of pointers as outlined above.
Note that the parameters to this function are two pointers, one to the first element in b and
one to the first element past the end of b.
*/
// Sort the range of pointers [begin; end)
void quicksort(const unsigned** begin, const unsigned** end)
{
//TODO
}
However, the Function is given const values, so is there any way to change the position of the input pointers?
A common Quicksort algorithm relies on the swap function, I tried calling
void swap (const unsigned** a, const unsigned** b){
const unsigned** temp = **a;
**a = **b;
**b = temp;
}
with
swap(begin, (end-1));
in the Quicksort Function. But that does not not work as the value for **a cannot be changed (Here, with the value **b), due to it being const.
So how would I even be able to sort the input pointers if I cannot change their order?
First of all, I know this stuff is really tricky when starting out with c/c++ and I had my fair share of confusion when I did. Therefore I will try to explain it the best way I can:
What you are trying to do in your swap function is changing the actual value of the integers behind the pointers by dereferencing two times and reassigning. You got an array of pointers which is basically a pointer to the first pointer and if you dereference that two times you end up at the actual integers, however you don't want that because this integer is constant.
Instead you want to end up at the pointers to the actual integers and swap those around. You can achieve that by dereferencing only once. If you try to reasign the pointer to change what it's pointing to, you can change the order of the array of pointers without ever touching the actual integers.
your swap function should look like this:
void swap(const unsigned int** a,const unsigned int** b) {
const unsigned int* temp = *a;
*a = *b;
*b = temp;
}
and the code where you call it could look something like this:
const unsigned int sort_without_touching[] = { 1 , 2 };
const unsigned int* ptr_array[] = {&sort_without_touching[0],
&sort_without_touching[1]};
//1 2
std::cout << *ptr_array[0] << " " << *ptr_array[1] << std::endl;
swap((ptr_array+ 0), (ptr_array+ 1));
//2 1
std::cout << *ptr_array[0] << " " << *ptr_array[1] << std::endl;

Access an element of a vector given the vector's pointer

I am trying to create a sorting function with the parameters being a pointer of a list and I am trying to access an element of the given list. Hopefully this code speaks for the problem better than I can:
void bubbleSort(std::vector<int> *L) {
unsigned int i = 0; int temp;
while(isSorted(*L)) {
if(i==L->size()-1) {
i = 0;
}
if(i<L[i]/*<-ERROR here.*/) {
temp = L[i+1]; // ERROR HERE
L[i+1] = L[i]; // ERROR HERE
L[i] = temp; // ERROR HERE
}
}
}
You don't need to painfully dereference every individual use of L (and indeed doing so is error-prone, as you've demonstrated by missing one in your answer).
Instead, just write:
void bubbleSort(std::vector<int> *Lptr) {
auto &L = *Lptr;
and keep the rest of the code the same.
NB. It would be even better to change the function itself, to
void bubbleSort(std::vector<int> &L) {
as it should have been written in the first place, but I'm assuming there's some artificial reason you can't do that.
The function accepts a pointer to an object of type std::vector<int>.
void bubbleSort(std::vector<int> *L) {
To access the original vector using the pointer, you can write either *L or L[0]. That is, both expressions yield an lvalue reference of type std::vector<int> & to the vector.
To get the i-th element of the vector using the subscript operator through the pointer, you can write either (*L)[i] or L[0][i],
However, in this if statement:
if(i<L[i]/*<-ERROR here.*/) {
You are trying to compare the variable i of type unsigned int to the object L[i] of type std::vector<int>. When i is not equal to 0, this yields a non-existent object of the vector type.
It seems you mean something like the following instead:
if ( (*L)[i] < (*L)[i+1] ) {
or:
if ( L[0][i] < L[0][i+1] ) {
or, vice versa:
if ( L[0][i+1] < L[0][i] ) {
Depending on whether the vector is sorted in ascending or descending order.
Pay attention to the fact that there is no sense in declaring the parameter as a pointer to a std::vector<int>. The function would be much clearer and readable if it accepted the vector by reference instead:
void bubbleSort(std::vector<int> &L) {
In this case, the if statement would look like this:
if ( L[i] < L[i+1] ) {
Although I prefer to change the source code as other answer. But, for this question, you can use ->at() function to access the element in a vector pointer.
if(i<L->at(i)) {
temp = L->at(i+1);
L->at(i+1) = L->at(i);
L->at(i) = temp;
}

Passing std::vector::data to function expecting type** (double pointer)

As the title describes, I am trying to pass the pointer to the data of a std::vector into a function expecting a double pointer. Take as an example the code below. I have an int pointer d which is passed to myfunc1 as &d (still not sure if call it the pointer's reference or what), where the function changes its reference to the beginning of an int array filled with 1,2,3,4. However, if I have a std::vector of ints and try to pass &(vec.data()) to myfunc1 the compiler throws the error lvalue required as unary ‘&’ operand. I have already tried something like (int *)&(vec.data()) as per this answer, but it does not work.
Just for reference, I know I can do something like myfunc2 where I directly pass the vector as reference and the job is done. But I want to know if it's possible to use myfunc1 with the std::vector's pointer.
Any help will be very much appreciated.
#include <iostream>
#include <vector>
using std::cout;
using std::endl;
using std::vector;
void myfunc1(int** ptr)
{
int* values = new int[4];
// Fill all the with data
for(auto& i:{0,1,2,3})
{
values[i] = i+1;
}
*ptr = values;
}
void myfunc2(vector<int> &vec)
{
int* values = new int[4];
// Fill all the with data
for(auto& i:{0,1,2,3})
{
values[i] = i+1;
}
vec.assign(values,values+4);
delete values;
}
int main()
{
// Create int pointer
int* d;
// This works. Reference of d pointing to the array
myfunc1(&d);
// Print values
for(auto& i:{0,1,2,3})
{
cout << d[i] << " ";
}
cout << endl;
// Creates the vector
vector<int> vec;
// This works. Data pointer of std::vector pointing to the array
myfunc2(vec);
// Print values
for (const auto &element : vec) cout << element << " ";
cout << endl;
// This does not work
vector<int> vec2;
vec2.resize(4);
myfunc1(&(vec2.data()));
// Print values
for (const auto &element : vec2) cout << element << " ";
cout << endl;
return 0;
}
EDIT: What my actual code does is to read some binary files from disk, and load parts of the buffer into the vector. I was having troubles getting the modified vector out of a read function, and this is what I came up with that allowed me to solve it.
When you write:
myfunc1(&(vec2.data()));
You are getting the address of a rvalue. The pointed int* is so a temporary that is destroyed right after the call.
This is why you get this error.
But, as #molbdnilo said, in your myfunc1() function, you are reassigning the pointer (without caring to destroy previously allocated memory by the way).
But the std::vector already manages its data memory on its own. You cannot and you must not put your hands on it.
What my actual code does is to read some binary files from disk, and load parts of the buffer into the vector.
A solution could be to construct your std::vector by passing the iterator to the beginning and the iterator to the end of the desired part to extract in the constructor's parameters.
For example:
int * buffer = readAll("path/to/my/file"); // Let's assume the readAll() function exists for this example
// If you want to extract from element 5 to element 9 of the buffer
std::vector<int> vec(buffer+5, buffer+9);
If the std::vector already exists, you can use the assign() member function as you already did in myfunc2():
vec.assign(buffer+5, buffer+9);
Of course in both cases, you have to ensure that you are not trying to access an out of bounds element when accessing the buffer.
The problem is that you cannot take the address of data(), since it is only a temporary copy of the pointer, so writing to a pointer to it makes not that much sense. And that is good that way. You DO NOT want to pass data() to this function since it would overwrite the pointer with a new array and that would break the vector. You can remove one * from the function and only assign to it and not allocate the memory there. This will work, but make sure to allocate the memory in the caller (with resize, just reserve will result un undefined behavior, since data() is only a pointer to the beginning of the valid range [data(), data() + size()). The range [data(), data() + capacity ()) is not necessary valid.

Pointer Variable to Locate the zero in the array

I am trying to make a code that tries to scan over an array for '0' using a pointer variable and then setting the address to that of the space in the array that has '0' in it. Unfortunately, my program is returning 10 as the value and 0 as an index. I would really appreciate any input to help me, and I'm trying to do this without changing main, so I dont think the following code is possible.
int* zerofinder(int array[], int q)
{
int* p = null; /// default value if there isn't a 0 in the array at
all
for (int k = q - 1; k >= 0; k--)
{
if (arr[k] == 0) // found an element whose value is 0
{
p = arr[k]; // change the value of p
break; // stop looping and return
}
}
return p;
}
Instead I think I have to use
void zerofinder(int array[], int x, int* p); function to change the pointer?
You pass the pointer by value.
Then you change where the pointer points to but that only modifies the local copy. It does not change the value of the pointer in the calling function.
You can resolve the problem using one of the following two approaches.
Pass the pointer by reference.
void findLastZero(int arr[], int n, int*& p);
Return the pointer from the function.
int* findLastZero(int arr[], int n);
This will change how you call the function. Instead of using:
int* ptr;
ptr = &nums[0];
findLastZero(nums, 6, ptr);
you can use:
int* ptr = findLastZero(nums, 6);
The problem is that you don't return the value you want from the function
int* findLastZero(int arr[], int n)
{
int* p = nullptr; /// default value if there isn't a 0 in the array at all
for (int k = n - 1; k >= 0; k--)
{
if (arr[k] == 0) // found an element whose value is 0
{
p = &arr[k]; // change the value of p
break; // stop looping and return
}
}
return p;
}
and
ptr = findLastZero(nums, 6);
Sometimes newbies think that pointers are something special, but pointers are values too, and obey the usual C++ rules about pass-by-value. If you pass a pointer to a function then changing the value of that pointer inside the function has no effect on the value outside the function, just like any other type.
This looks like a homework / test / quiz.
The answer to this quiz is: this can't be done without changing the main function.
Why?
As others have already told you, you need to change the findLastZero signature, either changing the p parameter type as int*& or int**, or return an int* from the function.
If you don't change the findLastZero signature (and the main), the findLastZero function has no way to change the outer ptr variable.

Returning arrays from function and losing its size

so let's say there is a function int* coeff(int n) that returns array (or rather, address to array[0]). Now, in this function this array has length of let's say 5, but when I call it like: int* array=SomeObject->coeff(n); that size is lost, and I don't know how can I get it back again. Any help please?
If you actually return a locally declared you have bigger problem than "losing its size".
First of all you have to remember that arrays decays to pointers, and once it has done that you no longer have any information about the array, just the pointer. And the size of a pointer is the size of the pointer and not what it points to.
The bigger problem might be you returning a locally declared array. When a function returns all variables declared locally in it goes out of scope. So what does the returned pointer then point to?
I assume your code looks something like this:
int* coeff(int n)
{
int* a = new int[5];
// ...
return a;
}
I suggest using a vector instead of an array:
#include <vector>
std::vector<int> coeff(int n)
{
std::vector<int> a(5);
// ...
return a;
}
You can always get the size of a vector by calling the .size() member function:
int main()
{
std::vector<int> x = coeff(42);
std::cout << x.size() << " elements in the vector!\n";
}