Pointer to a vector - c++

What is wrong with the following code
vector < double >* a;
a->push_back(25);
a->push_back(30);
a->push_back(15);
a->push_back(40);
cout << a->at(2) << endl;
It should print 15, but it prints nothing

a is a pointer but is not properly initialized... it must be like:
int main()
{
std::vector<double>* a = new std::vector<double>;
a->push_back(25);
a->push_back(30);
a->push_back(15);
a->push_back(40);
std::cout << a->at(2) << std::endl;
delete a;
return 0;
}

What is wrong ...?
You are using a pointer where an automatic duration value is more appropriate.
std::vector < double > a;
a.push_back(25);
a.push_back(30);
a.push_back(15);
a.push_back(40);
std::cout << a.at(2) << std::endl;

Your pointer wasn't initialized. Additionally, based on the answer by ΦXocę 웃 Пepeúpa ツ, make sure when you are working with pointers to use new/delete correctly. For every new keyword, there should be a delete. It is also good practice to avoid dangling pointers (pointers that do not reference anything) by setting them to NULL (as of C++11, it's recommended to use nullptr: NULL vs nullptr (Why was it replaced?) and What exactly is nullptr? questions offer some good explanations) when you are done.
However, in this case, I agree with Acorn. You shouldn't have to point to a vectorobject because of how it allocates memory. It should be sufficient to just use a vector for your solution.

Related

boost::scoped_ptr initialization with other scoped_ptr causes issue. Is this code correct

I am new to boost library and trying boost::scoped_ptr, it states this smart pointer cannot be copied or moved. But I was playing with some code and found an issue. I was able to create new instance of scoped_ptr and initialize it with existing valid scoped_ptr. So if one of the scoped_ptr's scope is over and deallocates the memory , other scoped_ptr still thinks its valid pointer and tries to access. It gave me error at runtime.
I am working on boost library version 1.66, with cygwin g++ compiler and using std=c++03 option while compiling.
#include<boost/scoped_ptr.hpp>
#include<iostream>
using namespace std;
int main(){
boost::scoped_ptr<int> pi(new int(9));
cout << *pi << endl;
cout << uintptr_t(pi.get()) << endl;
boost::scoped_ptr<int> ppi(pi.get()); // initialized with same memory pointed by pi.
cout << *ppi << endl; // so ownership of same memory is with pi.
cout << uintptr_t(ppi.get()) << endl; // as well as with ppi.
pi.reset(new int(12)); //its previous memory location pointing to 9 is deallocated.
cout << *ppi << endl; // throws garbage value..
cout << uintptr_t(ppi.get()) << endl; // shows same memory location it had previous memory shown by pi.
cout << *pi << endl;
cout << uintptr_t(pi.get()) << endl;
return 0;
}
So below is the snapshot of code run after compiling fine...
-> g++ -std=c++03 -Wall scoped_ptr.cpp
-> ./a.exe
9
25769804960
9
25769804960
-2144292696
25769804960
12
25769879920
Aborted (core dumped)
At end of execution is shows core dump, it incorrectly displayed -2144292696 in above run.
Also I checked boost::scoped_ptr was able to assign it to pointer
int * p = pi.get() statement compiles fine (should this work?)
Is above operation initializing scoped_ptr with other scoped_ptr valid?
Is above operation initializing scoped_ptr with other scoped_ptr valid?
No. Boost documentation reads:
explicit scoped_ptr(T * p = 0); // never throws
Constructs a scoped_ptr, storing a copy of p, which must have been allocated via a C++ new expression or be 0.
When you initialize one smart pointer with a raw pointer that is held by another smart one, you do not transfer ownership, you just make a copy of raw a pointer. Hence, that pointer will be deleted several times, which is undefined behavior.
What your code does is essentially this:
int* p = new int;
delete p; // when you call pi.reset()
delete p; // when ppi goes out of scope
.get() returns the stored raw pointer. It doesn't check its validity.
To transfer ownership, you should move-assign smart pointer itself. Simple example with std::unique_ptr and C++11:
auto p = std::unique_ptr<int>(new int);
// auto p1 = std::unique_ptr<int>(p.get()); // same error
auto p2 = std::move(p); // fine, transfers ownership from p to p2;
// p will not delete the raw pointer it previously held
boost::scoped_ptr does not support ownership transfer.

Why are pointers modified in a function ?

As a beginner in C++, first thing I came accross for functions is that they use a copy of the argument, for example if we execute this :
void add (double x){
x=x+3;
}
int main(){
double x=2 ;
add(x) ;
}
Then x would actually be equal to 2, not 5. Later on, learning about pointers, I found the following :
void fill (int *t){
for (int j=0, j<10, j++){
t[j]=j;
}
int main(){
int* p;
p = new int[10];
fill(p);
}
Now if we print what p contains, we find that it's indeed filled by the integers. I have some trouble understanding why it does that as I feel like it should have been the same as the first function ?
Thanks.
The reason it isn't the same as the first function is because you are passing the pointer by value. This means that if you modify the actual pointer, e.g by assigning to it, then it would only be in that state inside the function. The value that the pointer points to is still the original value, which will get modified since both copied pointers point to that same original value (don't forget notation of the form a[i] is equivalent to *(a + i), which does a dereference and is modifying the pointed value, not the pointer itself).
A small example that illustrates this would be the following (not accounting for memory leaks):
#include <iostream>
int test(int* x)
{
int* y = new int{10};
x = y;
std::cout << "Inside function: " << *x << "\n";
}
int main()
{
int* t = new int{5};
std::cout << "Before function: " << *t << "\n";
test(t);
std::cout << "After function: " << *t << "\n";
}
In first example you are using ordinary variable. When passing normal variable to function, like this, the function creates its own copy of the variable (it has same value as it has when you passed it, but it was copied to different place in memory). That is standard behaviour.
In second example you are using pointer: we can say that it points to the place in memory, where values are stored. Few of the advantages of them:
1) If you want to spare memory, but need to use same value in different functions -> mostly appplies to bigger objects than double, like array in your example
2) If you need to change value of variable/array/object in different functions
But careful, in the second function you still created copy, but not of value, but pointer. So basically, the "new" pointer is different object, but it is pointing to the same place in memory, so when accessing the value (which you are doing with [j]), you are editing the same place in memory.
It is not that easy concept to grasp, especially with more dimentional arrays, but hope this helped a little. You can learn some more in tutorials or c++ docs, for example this is a good one: https://www.geeksforgeeks.org/pointers-in-c-and-c-set-1-introduction-arithmetic-and-array/

Memory Address showing? C++

Not really sure what's going on here, I'm using Clion as my IDE which I don't believe has anything to do with this but I figured I'd add that information. My confusion comes from a function that I wrote
int Arry()
{
int Mynumbers [5] = {10};
std::cout << Mynumbers;
}
something simple. It should be assigning 5 integers the value of 10. But when I print out Mynumbers I am shown the memory address. Why is this happening, I thought that was what calling pointers was for. Thank you for your time.
Sincerely,
Nicholas
It is a bit complicated, and there are a few issues at play:
std::cout (actually, std::ostream, of which std::cout is an instance, does not have an overload of operator<< that understands plain arrays. It does have overloads that understand pointers.
In C++ (and C) an array name can be used as an expression in a place where a pointer is needed. When there is no better option, the array name will decay to a pointer. That is what makes the following legal: int a[10] = {}; int* p = a;.
The overload that takes a pointer prints it as a hexadecimal address, unless the pointer is of type char* or const char* (or wchar versions), in which case it treats it as a null terminated string.
This is what is happening here: because there isn't an operator<< overload that matches the array, it decays to the overload taking a pointer. And as it isn't a character type pointer, you see the hexadecimal address. You are seeing the equivalent of cout << &MyNumbers[0];.
Some notes:
void Arry() // use void if nothing is being returned
{
int Mynumbers[5] = {10}; // first element is 10, the rest are 0
//std::cout << Mynumbers; // will print the first address because the array decays to a pointer which is then printed
for (auto i : Mynumbers) // range-for takes note of the size of the array (no decay)
std::cout << i << '\t';
}
In C++, you can think of an array as a pointer to a memory address (this isn't strictly true, and others can explain the subtle differences). When you are calling cout on your array name, you are asking for it's contents: the memory address.
If you wish to see what's in the array, you can use a simple for loop:
for (int i = 0; i < 5; i++)
std::cout << Mynumbers[i] << " ";
The value of Mynumbers is in fact the adress of the first element in the array.
try the following:
for(int i=0; i<5;i++) {
cout << Mynumbers[i];
}

How to check if a pointer still points to valid memory in C++?

I have a pointer which equals to another pointer
I'd like to check if my pointer equals to a pointer which is not null.
int* ptr0 = new int(5);
int* ptr1 = ptr0;
delete ptr0;
if ( ?? )
{
std::cout << "ptr1 equals to a null ptr" << std::endl;
}
What should I write in the condition ?
Knowing that:
I don't want to set nullptr any of the ptr's after removal
I don't have access to ptr0 in my condition
Use a shared_ptr<T> combined with a weak_ptr<T>.
For example,
int main() {
std::tr1::shared_ptr<int> ptr0(new int);
std::tr1::weak_ptr<int> ptr1_weak(ptr0);
*ptr0 = 50;
// Depending on if you reset or not the code below will execute
//ptr0.reset();
if (std::tr1::shared_ptr<int> ptr1 = ptr1_weak.lock()) {
std::cout << "Changing value!" << std::endl;
*ptr1 = 500;
}
}
You can't. While in theory you could, depending on the implementation of new, check if the memory pointed to is currently in use there's no way to confirm that it's still the same object you were originally pointing to using only raw pointers.
You can use C++11 smart pointers to do something kinda like that, but I really don't think that's what you actually wanna do here.
delete does not result in a null pointer. It results in a dangling pointer, which is undetectable in general. So, you cannot.

modifying contents of local variable of a function in a subfunction through pointer

I have the following sample code. Just wanted to know if is valid to take address of a local variable in a global pointer and then modify it's contents in a sub function. Following program correctly modifies value of variable a . Can such practice cause any issues ?
#include <iostream>
#include <vector>
using namespace std;
vector<int*> va;
void func()
{
int b ;
b = 10;
int * c = va[0];
cout << "VALUE OF C=" << *c << endl;
*c = 20;
cout << "VALUE OF C=" << *c << endl;
}
int main()
{
int a;
a = 1;
va.push_back(&a);
func();
cout << "VALUE IS= " << a << endl;
return 0;
}
This is OK, as long as you don't try to dereference va[0] after a has gone out of scope. You don't, so technically this code is fine.
That said, this whole approach may not be such a good idea because it makes code very hard to maintain.
I'd say that if your program grows you could forget about a change you made in some function and get some weird errors you didn't expect.
Your code is perfectly valid as long as you call func() while being in the scope of a. However, this is not considered to be a good practice. Consider
struct HugeStruct {
int a;
};
std::vector<HugeStruct*> va;
void print_va()
{
for (size_t i = 0; i < va.size(); i++)
std::cout<<va[i].a<<' ';
std::cout<<std:endl;
}
int main()
{
for (int i = 0; i < 4; i++) {
HugeStruct hs = {i};
va.push_back(&hs);
}
print_va(); // oups ...
}
There are 2 problems in the code above.
Don't use global variables unless absolutely necessary. Global variables violate encapsulation and may cause overlay of variable names. In most cases it's much easier to pass them to functions when needed.
The vector of pointers in this code looks awful. As you can see, I forgot that pointers became invalid as soon as I left for-loop, and print_va just printed out garbage. The simple solution could be to store objects in a vector instead of pointers. But what if I don't want HugeStruct objects to be copied again and again? It can take quite a lot of time. (Suppose that instead of one int we have a vector of million integers.) One of the solutions is to allocate HugeStructs dynamically and use vector of smart pointers: std::vector<std::shared_ptr<HugeStruct>>. This way you don't have to bother about memory management and scope. Objects will be destroyed as soon as nobody will refer to them.