std::vector access violation on push_back [closed] - c++

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 1 year ago.
Improve this question
I have a method in class like this:
int Class1::addObject(Struct1 object)
{
object.objectID = objCounter;
objCounter++;
vector1.push_back(object); // this line throws exception
// unrelated line
return object.objectID;
}
Vector is defined and initialized as following:
std::vector<Struct1> vector1 = {};
The biggest problem is that this exception occurs sometimes and I am afraid that there is memory leakage.
I am using C++14 and I don't think there is problem with that (because I read somewhere that before C++11 vector was not allowed). Also the Struct1 object is initialized before calling this method, so it isn't about that neither.
Could it be because Visual Studio doesn't have Administrator privileges or it may be due to vector changing location in memory when adding more elements and process couldn't allocate more memory (I think this can be it)? The third possible suspect is multithreading: since I am accessing Class1 with 4 threads at the time, but every thread has it's own group of objects that it adds/removes, and that group is never the same for 2 or more threads?
Update 1:
Definition of Struct1 (copy and default constructors are added when someone suggested in answers)
struct Struct1
{
int objectID;
Struct1ObjectType objectType;
GLfloat array1[2];
GLfloat array2[3];
GLfloat objectSize;
Struct1() {}
Struct1(const Struct1& cs1)
{
objectID = cs1.objectID;
objectType = cs1.objectType;
for (int i = 0; i < 2; i++)
array1[i] = cs1.array1[i];
for (int i = 0; i < 3; i++)
array2[i] = cs1.array2[i];
objectSize = cs1.objectSize;
}
};

Re:
The third possible suspect is multithreading: since I am accessing Class1 with 4 threads at the time, but every thread has it's own group of objects that it adds/removes, and that group is never the same for 2 or more threads?
Regardless of objects being different, you can't access the same vector from multiple threads without synchronization.
One way of doing this is with mutex:
std::mutex m_lock;
then when you need to access that vector:
{
const std::lock_guard<std::mutex> l(m_lock);
vector1.push_back(object); // this line throws exception
}

The C++ standard library uses "copy semantics" for elements in its collections. The code line vector1.push_back(object); cause the copy-construction of a Struct1 object (the object that is stored inside the std::vector<>, which is a copy of the object that is in the parameter).
You haven't shown the definition of class Struct1 so I don't know how it's being copy-constructed, but I would check there to see if you have a programming bug in that code.

Related

how to move unique_ptr object between two STL containers [duplicate]

This question already has answers here:
Move out element of std priority_queue in C++11
(6 answers)
Closed 2 years ago.
#include <utility>
#include<unordered_map>
#include<queue>
using namespace std;
struct Task {
char t;
int cnt;
Task(char ch, int cnt):t(ch), cnt(cnt){};
};
struct CompTask {
bool operator() (const unique_ptr<Task>& a, const unique_ptr<Task>& b) {
return a->cnt < b->cnt;
}
};
class Schedule {
public:
int schedule() {
unordered_map<unique_ptr<Task>, int> sleep_q;
priority_queue<unique_ptr<Task>, vector<unique_ptr<Task>>, CompTask> ready_q; // max heap
ready_q.push(std::make_unique<Task>('A', 1));
auto& ptr = ready_q.top();
//sleep_q.insert({ptr, 1}); // compile error
sleep_q.insert({std::move(ptr), 1}); // compile error
// some other code...
return 1;
}
};
int main() {
return 0;
}
// error:
cpp:38:17: error: no matching member function for call to 'insert'
sleep_q.insert({std::move(ptr), 1}); // compile error
~~~~~~~~^~~~~~
Programming context:
I had a task class and the program attempts to simulate the task scheduling (which involves moving a task back and forth between a ready queue and a sleep queue).
I have two std containers for ready queue and sleep queue respectively, the priority_queue has value type unique_ptr<Task>, the other is
unorder_map (sleep queue) whose key is also unique_ptr<Task>. I had trouble moving the unique_ptr object from priorty_queue to unordered_map (shown in the code).
My questions are:
(1) how to insert an item into the unordered_map, I had compilation errors on doing that.
(2) in the problem context, which type of "pointer" would be preferred? unique_ptr<Task>, shared_ptr<Task>, or just Task*
There seems to be lack of move functionality out of std::priority_queue<>. You can go around it using const_cast, though in rare cases it might cause undefined behavior (when stored element type is const).
int schedule() {
unordered_map<unique_ptr<Task>, int> sleep_q;
priority_queue<unique_ptr<Task>, vector<unique_ptr<Task>>, CompTask> ready_q; // max heap
ready_q.push(std::make_unique<Task>('A', 1));
unique_ptr<Task> ptr =
std::move(const_cast<unique_ptr<Task>&>(ready_q.top()));
// ^ Here. priority_queue::top() returns `const&`.
ready_q.pop(); // remove moved element from priority_queue
sleep_q.insert(std::make_pair(std::move(ptr), 1));
// some other code...
return 1;
}
Reference: This answer
To move a unique_ptr between std containers requires destroying one unique_ptr (stored within the first std container) and passing the backing data to a new unique_ptr. This can be done with std::move. However, it's usually easier to use a shared_ptr. Which avoids the problem by allowing shared_ptr point to the same task to be in two std containers simultaneously. Even if just for a moment.
However, since you could have multiple shared_ptr objects pointing the same task the shared_ptr wouldn't work to uniquely identify the task. To do that, I would recommend creating a Task Id for each task. A simple integer would work for this, as long as you guarantee it's unique to that task. An integer task Id would work well with a map since the Id could be used as the key.

Custom reference type [closed]

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I am writing a wrapper around a C-API.
(i) Let capi_array_data capi_get_array(void) be a function contained within this library returning a struct containing metadata about a heap-allocated array managed by said API. It would look something like struct capi_get_array { size_t length; int* arr }; (using int for simplicity)
(ii) Such an array can be created by the user manually with malloc, new, std::vector, etc. It must then be registered with void capi_register_array(int*).
I want to make a wrapper class, call it MyArrayWrapper, managing such an array with the anatomy of an STL container, supporting operator[], begin, back, etc. In (i) this wrapper would not own the data, but in (ii) it would. My question now is, whether I should
(a) have one single class that can be constructed using either a std::initializer_list (or variadic template for that matter) or an int* returned by the API;
(b) have separate classes named something like MyArrayWrapperRef and MyArrayWrapper, the first handling (i) and the second handling (ii);
(c) optimally have the syntax MyArrayWrapper& for (i) and MyArrayWrapper for (ii); can this be done?
With (a) there could come up confusion, as one class does two things, which breaks the single-responsibility principle. Answers to questions like "does the copy constructor conduct a deep of shallow copy?" will not be obvious and would require further documentation.
(b) seems like a good choice, but now there are multiple cases: MyArrayWrapper, MyArrayWrapper&, MyArrayWrapperRef, MyArrayWrapperRef&. How would they differ? What about const references? This might even require another class MyArrayWrapperConstRef and again leads to confusion.
(c) is optimal and seems natural with other classes, but I don't know of a way to make it work. I could make a wrapper around capi_get_array returning a MyArrayWrapperRef, but I would have to save the source of the reference somewhere, right?
With (a) there could come up confusion, as one class does two things,
which breaks the single-responsibility principle.
You can also see it the other way around: The single responsibility of the wrapper is to hide the real ownership and who cleans up what.
Lets say you have this:
struct arr_data {
int* a;
unsigned size;
};
arr_data get_arr(){
arr_data ret;
ret.size = 5;
ret.a = new int[ret.size];
return ret;
}
void reg_arr(arr_data x){
static arr_data store = x;
}
Then a simple wrapper could look like this:
struct wrapper {
std::shared_ptr<arr_data> data;
// implement container-like interface
};
wrapper make_non_owning_wrapper() {
auto res = new arr_data();
*res = get_arr();
return { std::shared_ptr<arr_data>(res,[](arr_data* x){
std::cout << "delete x only\n";
delete x;
}) };
}
wrapper make_owning_wrapper() {
auto res = new arr_data();
res->size = 5;
res->a = new int[res->size];
return { std::shared_ptr<arr_data>(res,[](arr_data* x){
std::cout << "delete both\n";
delete[] x->a;
delete x;
})};
}
int main(){
auto v = make_owning_wrapper();
auto w = make_non_owning_wrapper();
auto z = v;
}
Using a shared pointer you can choose a) what to do on clean up and b) what happens when copying a wrapper without causing great confusion ;).

Trying to delete a dynamically allocated object causes a run-time crash [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 5 years ago.
Improve this question
I'm working on optimizing my current CLI project. When looking through the code and debugging I've noticed that I haven't released some dynamically allocated memory in a class. Here's how my code looks:
"Coordinates.h"
#pragma once
#include <Windows.h>
#define LENGTH 40
#define WIDTH 15
struct Coordinate
{
int x = 1;
int y = 1;
};
"Laser.h"
#pragma once
#include "Coordinates.h"
class Laser
{
private:
Coordinate* initCoord;
char icon;
public:
Laser(int x, int y);
char getIcon() const;
Coordinate* getCoord();
void move();
};
"Laser.cpp"
#include "Laser.h"
Laser::Laser(int x, int y)
{
initCoord = new Coordinate;
initCoord->x = x;
initCoord->y = y;
icon = '~';
}
char Laser::getIcon() const { return icon; }
Coordinate* Laser::getCoord() { return initCoord; }
void Laser::move()
{
++initCoord->x;
}
I've tried adding a destructor (declaring it in the header file first of course) which clears up the memory allocated for initCoord which looked something like this:
Laser::~Laser()
{
if(initCoord != nullpr) delete initCoord;
}
After adding that it caused a run-time error. "ProgramName.exe has stopped working..." Objects of this class are stored in a simple vector which gets cleared at one time of the program. The problem is that the crash happens before it even reaches the lasers.clear() line. I honestly have no idea why this crash is happening and would appreciate some help. Thank you! :)
If you consider this code
int main() {
Laser one(0,0);
{
Laser two = one;
cout << two.getCoord()->x << endl;
}
return 0;
}
What do you expect to be written?
"0"
which mean that the coordinate points to the same structure as one which again means that when the first } happens and two gets destroyed one doesn't have a valid coordinate any more.
When you have a pointer member you need to either disable copying/assigning or implement them.
In this case you could also have been rescued if you had used a std::unique_ptr instead of the raw pointer (which also saves you the delete).

Copy constructor in C++ with mutex [duplicate]

This question already has an answer here:
Multithreading with templated class member function
(1 answer)
Closed 7 years ago.
I have an object like this:
class Blocking_queue
{
private:
queue<T> my_queue;
unsigned int dim;
mutex m;
condition_variable cv;
}
In my main I want to create some threads which call the object methods:
Blocking_queue<int> q(6);
thread t(close, q);
How can I do my copy constructor with the mutex? I think that I cannot simply do like this because it's not copiable
Blocking_queue(const Blocking_queue& source){
this->queue = source.queue;
this->dim = source.dim;
this->m = source.m;
this->cv = source.cv;
}
If you really want to copy the contents of the queue and have two separate, independent queues, you should copy the contents and initialize new mutexes, like this:
Blocking_queue(const Blocking_queue& source){
this->queue = source.queue;
this->dim = source.dim;
}
Or better yet, like this:
Blocking_queue(const Blocking_queue& source):
queue(source.queue),
dim(source.dim) {
}
But it's probably not what you want. If you want this object to be shared between threads, pass it by reference:
Blocking_queue<int> q(6);
thread t(close, ref(q));
Or, if the thread may last longer than the scope of the function where you defined the queue, use shared pointers to make sure the object remains valid.
auto q = make_shared<Blocking_queue<int>>(6);
thread t(close, q));

C++ Vector Push_back producing Weird Side Effect

While I was using STL vector to store class objects,, I observed a very weird side effect, where push_back method modifies the Existing Data!
Basically I have a class containing several fields as follows:
class MyClass {
MyClass(std::string s, int i) {
StringValue = s;
IntValue = i;
}
std::string StringValue;
int IntValue;
}
I have a vector that contains the POINTERS to MyClass objects.. and then I am basically pushing back references to objects:
std::vector<MyClass*> MyVector;
MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);
MyVector.push_back(&c1);
// Result:
// *MyVector[0] ==> ("Class 1", 1)
MyVector.push_back(&c2);
// Result:
// *MyVector[0] ==> ("Class 2", 2) ??why 2??
// *MyVector[1] ==> ("Class 2", 2)
Do you see the strange result that I got?? I've set breakpoints after each push_back statement,,, and this weird thing happened.
The first push_back statement worked fine. But then the second push_back statement MODIFIED the content of the first element, which doesn't make sense to me..
I'm assuming that it has something to do with me storing References instead of actual objects inside the vector.... but I can't figure out what is wrong.
How can I handle this issue? Any insights?
Thanks
UPDATE:
(simplified code)
MyClass c1("CLASS 1", 1);
MyClass c2("CLASS 2", 2);
MyClass temp;
while (int i=0; i<2; i++) {
temp = c1;
MyVector.push_back(temp);
}
You guys are right,, I get what I'm doing wrong here.. The actual object gets destructed in every loop.. What's the best way to fix this while keeping the current structure?? I'ts hard to explain but I would like to keep this structure (keeping temporary buffer outside the loop).. is this possible?
I'm going to out on a limb and use my psychic powers to derive the real code, rather than the simplified code in the question. Your real code looks like... drumroll...
class MyClass {
// ...
};
void addInstance(std::vector<MyClass*>& MyVector, int i) {
MyClass c("", i);
MyVector.push_back(&c);
}
int main() {
addInstance(MyVector, 1);
addInstance(MyVector, 2);
// ...
}
Here's a working example to demonstrate the problem, which does indeed output "2, 2" (although that's not guaranteed because you're invoking undefined behaviour):
http://ideone.com/PxiUx9
Edit: My psychic powers said "auto variable in a function" when (now that we have the updated question) it was really "auto variable in a loop". Not too far wrong. :-)
You're storing the address of an automatic variable beyond its lifetime, which is not allowed. The address is being re-used on each call, hence each pointer stored is the same, and happens to point to the memory that was last used to store the most recently created instance of MyClass (though that's not guaranteed).
You need to (preferably) store copies of those automatic variables rather than pointers to them, or (less preferably) create them with new and later delete them with delete.
To store copies, you need to use a std::vector<MyClass>. Here's an example of how you might do that: http://ideone.com/4rIijM Note that once your class gets more complex you might need to define a copy constructor, destructor and assignment operator - look up the "rule of three". If you're using C++11, also look up the "rule of five".
For anyone looking for a clear and concise explanation:
Why does an object get destroyed when pushing it to a vector?
You are creating a temporary object:
m_foos.push_back(Foo(a));
// ^^^^^^
Solution:
The function emplace_back is what you want to use:
m_foos.emplace_back(a);
Check out: push_back vs emplace_back
EDIT---
Also, I noted that when compiling with CLion, the error is not fixed. It is also known to be an error on Visual Studio. In other words, be careful with your IDE.