I am getting a seg fault at sem_init. I am trying to create a unnamed sem. Thank you
Appreciate some help on this.
sem_t *t;
int status = sem_init(t,1,1);
sem_t t;
int status = sem_init(&t,1,1);
This is C API, so all functions use pointers, not references.
Furthermore there are no constructors, hence the existence of sem_init which is used to initialize a structure object t.
It doesn't allocate an object, double ptr would be needed for that.
See e.g. man 3 sem_wait for an example.
Related
I’m a C++ beginner with a background in Python, Java, and JS, so I’m still learning the ropes when it comes to pointers.
I have a vector of shared pointers. Inside of a different function, I assign a shared pointer to a variable and add it to the vector. If I try to access the added element after that function exits, a segmentation fault happens:
class Bar
{
private:
std::vector<std::shared_ptr<Foo>> fooVector;
}
void Bar::addToFoo()
{
std::shared_ptr<Foo> foo (new Foo(…));
fooVector.push_back(foo);
}
void Bar::otherMethod()
{
// this method gets called sometime after addToFoo gets called
…
fooVector[anIndex]->baz(); // segfaults
…
}
But, if push_back a shared pointer and not a variable, it works.
// this works:
fooVector.push_back(std::shared_ptr<Foo>(new Foo(…)));
// this segfaults:
std::shared_ptr<Foo> foo (new Foo(…));
fooVector.push_back(foo);
I believe it happens because the foo variable gets deleted when the addToFoo function exits (correct me if I’m wrong). How do you push_back a shared_ptr variable to a vector of shared_ptrs in C++?
Why Use A Variable
Though pushing shared_ptrs to vectors directly without variables works, I prefer to use variables in order to do this:
std::shared_ptr<Rider> rider;
switch (iProcessorModesParam)
{
case PEAKS_MODE:
rider = std::shared_ptr<Rider>(new PeaksRider(…));
break;
case RMS_MODE:
rider = std::shared_ptr<Rider>(new RMSrider(…));
break;
}
volumeRiders.push_back(rider);
PeaksRider and RMSrider are subclasses of Rider. I want to store all subtypes of Rider in the same vector of Riders. I learned that adding subtypes of Rider to a vector of Riders doesn’t work and pointers are needed in order to achieve this kind of polymorphism:
std::vector<Rider> // doesn’t work with subtypes
std::vector<*Rider>
std::vector<std::shared_ptr<Rider>>
Having the std::shared_ptr<Rider> rider; variable avoids repeating the .push_back(…) code for each type of Rider.
Instead of assigning shared pointer, user reset method.
rider.reset(new PeaksRider(…));
other that this, your code snippets seems to okay to me.
segfault may have caused because of the index variable ( which may be out of range). i suggest you to use .at(index) for accessing pointer from vector and wrap that part of code in a try..catch block and see what is the real error.
And regarding...
I believe it happens because the foo variable gets deleted when the addToFoo function exits (correct me if I’m wrong).
This is not true, share_ptrs use a local counter for #of references. as soon as you pushed the pointer to vector the counter gets incremented to 2 and event after control exits the function the counter is decremented to 1. so, your object is not destroyed yet.
There is no problem on creating a shared pointer instance, storing it in a variable, and doing a push_back to a vector after that. Your code should be fine as long as the index that you use when calling "otherMethod" is valid. However, I have a couple of suggestions for your code:
When you create a shared_ptr, it is highly recommended to do it through "std::make_shared" to ensure the safety and correctness of your code in all situations. In this other post you will find a great explanation: Difference in make_shared and normal shared_ptr in C++
When accessing positions of a vector using a variable that may contain values that would cause an out-of-bounds access (which usually leads to segmentation faults) it is a good practice to place asserts before using the vector, so you will detect these undesired situations.
I just wrote a small snippet that you can test to illustrate what I just mentioned:
#include <iostream>
#include <vector>
#include <memory>
#include <cassert>
class Foo
{
public:
int data = 0;
};
class Bar
{
public:
void addNewFoo(int d)
{
std::shared_ptr<Foo> foo(new Foo());
foo->data = d;
fooVector.push_back(foo);
}
void addNewFooImproved(int d)
{
auto foo = std::make_shared<Foo>();
foo->data = d;
fooVector.push_back(foo);
}
void printFoo(int idx)
{
assert(idx < fooVector.size());
std::cout << fooVector[idx]->data << std::endl;
}
private:
std::vector<std::shared_ptr<Foo>> fooVector;
};
int main()
{
Bar b;
b.addNewFoo(10);
b.addNewFoo(12);
b.addNewFooImproved(22);
b.printFoo(1);
b.printFoo(2);
b.printFoo(0);
}
I am learning C++ and I can not figure this out. I do not want to post all my code but feel that it is necessary as it is overall short.
#include <iostream>
#include "MathObject.h"
using namespace std;
int main(int args, char *argv[]){
MathObject mo = new MathObject(3,4);
int sum = mo.sum();
cout << sum << endl;
return 0;
}
#include <iostream>
#include "MathObject.h"
using namespace std;
MathObject :: MathObject(int n, int m){
num1 = n;
num2 = m;
}
int MathObject :: sum(){
return num1+num2;
}
class MathObject{
private:
int num1;
int num2;
public:
int sum();
MathObject(int n, int m);
};
So this is all in 3 separate files, I am using an example from my prof as a template on how to make classes and header files to organize our code. This always returns the error:
conversion from 'MathObject*' to non-scalar type 'MathObject' requested| ||=== Build finished: 1 errors, 0 warnings (0 minutes, 0 seconds) ===|
I have been going over the code for a while now but I can not get it! If anyone can point out what is wrong I would love to hear.
Thanks!
In C++ you can just make an object on the stack:
MathObject mo(3,4);
This statement creates a MathObject called mo on the stack, that will be automatically destroyed when main returns. This should be your preferred way of creating objects.
The new operator in C++, unlike the new operator in Java or C#, is not needed for creating an object and should generally be used very sparingly. It allocates memory from the heap for holding the object, which allows the object's lifetime to extend beyond the current function. But that also means that you are responsible for cleaning up with delete after you are done using the object, or the memory will be leaked.
MathObject *mo = new MathObject(3,4); // Never do this!
This is terrible code. It's a) inefficient (allocating from the heap with new is much more expensive than the stack) and b) unsafe, because if for some reason you fail to delete mo; (sometimes the reason is out of your control, such as an exception being thrown through your code) the memory is leaked.
std::unique_ptr<MathObject> mo(new MathObject(3,4));
This uses new to create a MathObject object on the heap, and stores the returned pointer in a unique_ptr object created on the stack. The unique_ptr object will automatically delete the pointer stored in it when the unique_ptr is destroyed. This is safe, but it's still much slower than the first version.
Your declaration of MathObject is faulty. If you are dynamically allocating a MathObject, it should be
MathObject * mo = new MathObject(3,4);
And the sum function should be called using -> operator like this:
int sum = mo->sum();
Or if you want to create an object on the stack, you should not be using the new operator.
MathObject mo(3,4);
int sum = mo.sum();
That will do the trick.
Edit:
Here is how it works on the top level:
The new operator searches for the free memory for your object (In your case that is a MathObject), and initializes a new object in the space using the constructor arguments you passed. Then, it returns a pointer to this newly created object. So on the lhs, you should be declaring a pointer that can point to a MathObject. That is why we have MathObject * mo and not Mathobject mo.
I hope that helps!
the way you are creating a new object is how you would do it in C# or Java.
in C++ it is better to avoid using new because you will have to keep memory management in mind and also it is much slower.
the little piece of code shows you how to use constructors:
#include <iostream>
using std::cout;
using std::endl;
class MathObject{
public:
MathObject (){
cout<<"Calling Default constructor"<<endl;
}
MathObject (int i, int j){
x = i;
y = j;
cout<<"Calling constructors with two parameters"<<endl;
}
private:
int x, y;
};
int main () {
MathObject mo;
MathObject mo2(3,4);
}
output:
Calling Default constructor
Calling constructors with two parameters
It's your object initalisation, here:
MathObject mo = new MathObject(3,4);
You create a local object mo, then you you create another object somewhere on the heap and new returns a pointer to it. So your compiler understands that you want to assign a pointer to mo.
Replace your line with:
MathObject mo = MathObject(3,4);
or even:
MathObject mo(3,4);
Please note that these two forms give in fact the same result: in both case, the compiler generates only one object and one call to the constructor with the parameter(3,4), despite the "=" operator. To know more about this, look at: http://www.gotw.ca/gotw/001.htm .
I am trying to create a tree structure using some handler functions that are called while reading a stream. I think the problem is that my variables are created in the function's scope and disappear when the function ends, leaving pointers that point to nothing.
I am not sure what approach to take to keep the objects in memory, whilst still allowing the tree to be scalable.
I have made a simplified version of the code: it compiles and runs but the parent-child relationships of the 'Segment' objects are all wrong.
class Segment
{
public:
Segment* parent;
list<Segment*> children;
string name;
};
void OpenSegment(Segment* p_segCurrentseg);
void CloseSegment(Segment* p_segCurrentseg);
int _tmain(int argc, _TCHAR* argv[])
{
Segment parent;
parent.name="parent";
Segment* p_segCurrentseg=&parent;
OpenSegment(p_segCurrentseg);
OpenSegment(p_segCurrentseg);
OpenSegment(p_segCurrentseg);
CloseSegment(p_segCurrentseg);
return 0;
}
void OpenSegment(Segment* p_segCurrentseg)
{
Segment child;
child.name="child";
p_segCurrentseg->children.push_front(&child);
child.parent=p_segCurrentseg;
p_segCurrentseg=&child;
}
void CloseSegment(Segment* p_segCurrentseg)
{
p_segCurrentseg=p_segCurrentseg->parent;
}
There are couple of problems in your code.
You are passing p_segCurrentseg by value and assigning to another pointer. This has no effect on the variable in the calling function.
As you already suspected, you are trying to assign p_segCurrentseg to point to a variable that will be gone when you return from the function.
What you can do:
Pass p_segCurrentseg by reference to a pointer.
Create an object from the heap and assign p_segCurrentseg to point to it.
Here's my suggestion for OpenSegment:
void OpenSegment(Segment*& p_segCurrentseg)
{
Segment* child = new Segment;
child->name="child";
p_segCurrentseg->children.push_front(child);
child->parent=p_segCurrentseg;
p_segCurrentseg=child;
}
The problem is in the OpenSegment() method, particularly in these 3 lines:
Segment child;
child.name="child";
p_segCurrentseg->children.push_front(&child);
First, child is a local variable and created on the stack. You then push the address of child into your list. When OpenSegment() returns, the address of child contains garbage since storage for local variables are deallocated.
The solution is to define child as a pointer to Segment, create it on the heap so it lives even after OpenSegment() returns. You have to make sure to deallocate its memory too. The proper place is to define a destructor for your Segment class. In it, iterate through the list (of children segments) and deallocate the memory for each child.
pointer segfault problems...
I've been doing c++ for some weeks meanwhile but i ran again into that issue.
basically i have these classes given. I cant change them. I start with an instance of _ns3__importAuftragResponse kout;
class SOAP_CMAC _ns3__importAuftragResponse
{
public:
ns2__SOAPImportResult *return_;
...
class SOAP_CMAC ns2__SOAPImportResult
{
public:
bool *error;
int *numberOfIgnoreds;
....
My code needs to check for the numberOfIgnoreds
first approach
ns2__SOAPImportResult* imp_result;
imp_result = kout.return_;
int num;
num = *imp_result->numberOfIgnoreds;
or i use
ns2__SOAPImportResult imp_result;
imp_result = *(kout.return_);
int* num;
*num = *imp_result.numberOfIgnoreds;
I mostly get segmentation fault
I know generally what happens at runtime but cant come up with the correct ode. PLease help.
EDIT
made progress thx to your answer, Nawaz , but still need some understanding
ns2__SOAPImportResult * imp_ptr = new ns2__SOAPImportResult;
imp_ptr = kout.return_;
int * num = new (int);
// next line segfaults
*num = *imp_ptr->numberOfIgnoreds;
what's hard for me to understand is, how or why allocate memory for something that is already "there" as there is the member return_ of the object kout
So is it correct to say I need to allocate memory for the variable I assign it to (which is of same type of course)?
Most likely you've not allocated memory for the following members which you're using in the code you've quoted.
ns2__SOAPImportResult *return_; //in the class _ns3__importAuftragResponse
int *numberOfIgnoreds; //in the class ns2__SOAPImportResult
Other than this I don't see anything where things might go wrong!
Make sure you allocate memory for these members (and all other pointers in your program) before using them. You can use new to allocate memory. Or alternatively, you can use malloc() as well. Whatever you use, use it consistently, and deallocate the memory once you done, using delete or free() respectively!
This looks like gsoap. In that case you must use soap_malloc to allocate memory which you return.
For example on the FAQ page, you will find this example:
int ns__itoa(struct soap *soap, int i, char **a)
{ *a = (char*)soap_malloc(soap, 11);
sprintf(*a, "%d", i);
return SOAP_OK;
}
I'm trying to write a linked queue in C++, but I'm failing so far. I've created 2 files by now: my main.cpp and box.h. When trying to use my box, I receive the following message:
Description Resource Path Location Type
conversion from ‘Box*’ to
non-scalar type ‘Box’
requested main.cpp /QueueApplication line
14 C/C++ Problem
My code is as follows:
box.h
#ifndef BOX_H_
#define BOX_H_
template<class T>
class Box
{
public:
Box(T value)
{
this->value = value;
this->nextBox = NULL;
}
T getValue()
{
return this->value;
}
void setNext(Box<T> next)
{
this->nextBox = next;
}
private:
T value;
Box<T> nextBox;
};
#endif /* BOX_H_ */
main.cpp
#include<iostream>
#include "box.h"
using namespace std;
int main(int argc, char** argv)
{
Box<int> newBox = new Box<int>();
cout << "lol";
cin.get();
cin.ignore();
return 0;
}
Could you guys help me?
PS: before someone ask me why not to use stl ... I'm in a data structures class.
Removing unimportant stuff, we see you've declared a new class like this:
template<class T>
class Box
{
T value;
Box<T> nextBox;
};
How big is Box<T>?
Clearly
sizeof Box<T> >= sizeof(Box<T>::value) + sizeof(Box<T>::nextBox)
sizeof Box<T> >= sizeof(T) + sizeof(Box<T>)
0 >= sizeof (T)
uh-oh
The problem is with this line
Box<int> newBox = new Box<int>();
The new operator returns a pointer to a Box object created on the heap. The pointer will be of type Box<int>*. The left side of that expression declares a Box object. You can't directly assign a pointer-to-X to an X. You should probably just omit the new keyword unless you have a reason to want to manage the storage lifetime of the object manually. Incidentally, I'm betting you come from Java, where new is always required to create objects. Not so in C++.
Also I think it's awesome that your data structures class is introducing you to templates right off the bat.
I believe your nextBox should be a pointer.
Box<T> * nextBox;
Method setNext should deal with pointers too.
void setNext(Box<T> * next)
And newBox should be a pointer.
Box<int> * newBox = new Box<int>();
Since you come from a Java background, you are assuming that all of your objects are references. Syntax is a little different in C++.
There are multiple problems here.
First of all, in order to implement a linked list (or a queue that uses a linked list) in C++ you need to use pointers. In Java everything is a reference. C++, on the other hand, makes a clear distinction between objects and pointers to objects. (There are also references to objects, but they are irrelevant here).
Let's also forget the templates for a moment, because they are not part of the problem here.
class Box
{
int value;
Box nextBox; // wrong! should be a pointer
};
is wrong, because nextBox must be a pointer to the next element of the list/queue. The correct
way would be Box *nextBox;
By the same token setNext() should also take a pointer to Box as its argument. setNext(Box b) is an example of pass-by-value, i. e. this member function (method in Java lingo) gets its own copy of the entire Box object. This could lead to performance issues if the object is large, not to mention that any changes done to it by the function will be invisible to the caller. What you want instead here is pass-by-reference, which is accomplished by using a pointer.
The final point is that new in C++ always returns a pointer. You should have Box<int> *newBox = new Box<int>;
When you use new, you get a pointer to an object, not a plain object. Declare your variable as a pointer or just allocate your object on the stack instead.
I hope this makes sense to you, since if it doesn't, you should probably go back and read more about the basics of OOP in C++.
Guys. No raw pointers in C++ unless you really need them. Please. Especially for some poor soul who doesn't even know that operator new returns a pointer. Get a std::auto_ptr or a std::shared_ptr.