Segmentation fault i cant figure out - c++

I have the following constructor:
Timing::Timing():
_numMes(INIT_NUMMES),_msgs(new allMSgs*[NUMBER_OF_MSGS])
{
cout<<"build timing OK\n";
}
allMSgs is a struct :
typedef struct AllMSgs
{
double msg;
Agent* dedicatedTo;
}allMSgs;
and the declaration of it is done like this:
allMSgs** _msgs;
but when i try to reach for a field in the array like this:
_msgs[loc]->dedicatedTo=agent->getPointsTo();
i get a segmentation fault.
NUMBER_OF_MSGS is 1000
loc is 0,1,2.... (less then 1000);
help please

You've made an array of pointers, but not set them to point anywhere valid yet. You either need to change it to be simply:
allMSgs* _msgs;
and:
new allMSgs[NUMBER_OF_MSGS]
Or call new for each pointer in the allMSgs array.
Better yet though you could just use a std::vector or other container, with std::vector<allMSgs> _msgs;, which you can use like it was an array in most cases. You can initalise it with a size too.

You have only allocated the array itself. You need to allocate each and every item of the array too. In the constructor, add a for loop that allocates all of the items.
for (int i = 0; i < NUMBER_OF_MSGS; i++)
_msgs[i] = new allMSgs();
You can also just define the array as an array of allMSgs and not pointers to allMSgs.
allMSgs* _msgs;

Related

C++ How to create a dynamic array of vectors?

I'm having problem initialising an array of std::vectors.
I'm declaring and initialising it like this:
vector<component_change*>* _changes;
_changes = new vector<component_change*> [numThreads];
in the hope that it's in the same form as this:
int * foo;
foo = new int [5];
but when I hit a breakpoint after the initialisation, _changes' size is 0.
What am I doing wrong and how can I fix it?
I don't want to use a vector of vectors as the number I need remains constant throughout the program but depends on the current hardware. And I'm not just looking for a single vector (Each vector will be used by a different thread then merged when the threads have finished their tasks).
Thanks guys! :)
Your program is correct. But you misinterpreted the debugger. _changes's size is not 0, but the first vector in your array (the one _changes points at) is empty. Thats because the debugger does not know if _changes points at a single element or an array (in that case the compiler would not know how many elements are in that array). Simply use a vector and call std::vector::shrink_to_fit.
If the size can be determined at compile time use a std::array. If the size is a run-time argument then use a vector and don't change the size of the container.
Are you interested in have a vector for each thread, or a vector containing items used by each thread? I assumed the later, but my answer could be adapted.
This is using a statically sized array; (this syntax is close).
const int NUMBER_OF_THREADS = 5;
component_change* _changes[NUMBER_OF_THREADS] =
{
new component_change(1),
new component_change(2),
new component_change(3),
new component_change(4),
new component_change(5)
}
If the number of threads is dynamic, you will have to use a new...
int NUMBER_OF_THREADS = system.getThreadCount();
component_change* _changes = new component_change[NUMBER_OF_THREADS];
for (int i = 0; i < NUMBER_OF_THREADS; i++)
{
_changes[i] = new component_change(i+1);
}
If you want to a std::vector:
int NUMBER_OF_THREADS = system.getThreadCount();
std::vector<component_change*> _changes;
_changes.reserve(NUMBER_OF_THREADS);
for (int i = 0; i < NUMBER_OF_THREADS; i++)
{
_changes.push_back(new component_change(i+1));
}
I think you're kind of mislead, this size that you are reading belongs to the vector in the first element of the array. Its size is equal to 0 since no elements have been inserted in the vector yet.
new vector is usually wrong.
You should use, with most preferred if possible first,
std::vector<component_change> _changes(numThreads);
or
std::vector<std::unique_ptr<component_change>> _changes(numThreads);
or
std::vector<component_change*> _changes(numThreads);
or if each element of the vector should itself contain an array of components (it's not clear in your question)
std::vector<std::vector<**component_change**>> _changes(numThreads);
Declaring the component as one of the above ways, depending on your needs.
Note that the pointers begin not pointing to anything. You'd have to allocate the individual components as a separate step.
The following creates an array of numThreads vectors, not a vector of numThread elements.
new vector<component_change*> [numThreads]

Deleting 2-dimensional array

I'm storing a list of text files inside a vector, and, want to read the contents of the text file into a 2-dimensional array for each iteration:
for(unsigned i=0; (i < files.size()); i++)
{
std::string file = dir + "/" +files[i];
double** training_vars = new double*;
training_vars = readFromFile(file);
delete[] &training_vars;
}
I let the function readFromFile decide the size of the array and return this array.
The problem that I am having is that each time this runs, I get a bad_alloc error. I cannot size the 2D array inside the main either so I'm kind of stuck as to what to do here in order to properly delete the array. Any ideas please?
Your program has undefined behavior, this line is invalid:
delete[] &training_vars;
Because &training_vars was not allocated by a new [] (note that training_vars is simply a pointer to a double, nothing more).
You probably want readFromFile to do the allocation for you, possibly by returning a smart pointer, or, better, pass a vector<> by const reference to it.
Ideally, always use std::vector<> and get rid of C-style arrays, it was designed to avoid situations like this.
Note :
Your for loop has unnecessary parenthesis, and could be replaced by a for-range loop :
for(auto& file : files)
{
...
}
You really must at least wrap this library with proper "RAII" objects and use modern C++. Something like this will work better for you.
for ( auto file : files )
{
std::shared_ptr< double * > training_vars( readFromFile( file ) );
// ... the rest of your code that uses training_vars
}
And as mentioned elsewhere delete[] &training_vars; will probably seg fault. You're passing the address of the stack local "pointer-to pointer-to double" named training_vars to delete. What you want is the address contained in that local variable.

how do I empty/clear vector and array in c++

let's say I have a class, A
Class A {
int x[100];
vector<int> y;
Fill(x);
Fill(y.begin());
B(x);
B(y.begin());
}
Class Fill (pointer) {
*pointer = 0;
++pointer;
*pointer = 1;
++pointer
}
Class B(container) {
//how do I clear/empty the array and the vector passed by class A given only the pointers to them?
//I must clear an array and a vector in THIS class.
//I DO NOT want to fill them with 0s.
//x and y.begin are POINTERS to the first element of the container, not containers
}
dsfsdakfgnsdfgsf
dg
sdf
gsdf
ghsdf
g
sdfg
ersg
s
Thank you in advance.
For vector:
some_a_pointer->y.resize(0);
You can't do it with just an iterator (y.begin()).
An array's size can never change, so the best you can do is fill it with 0.
std::vector has a method called clear that will clear all the elements.
So my_vector.clear(); will clear everything. However you can't really do the same for arrays. It's just not possible. At best you can fill them with zeroes or go the wrong way and dynamically allocate the array and then delete it. I would rather not deal with memory issues though so I'd just fill them with zero.
C++11 has a class called std::array<T,N> for static arrays of a compile time size and it has a method called fill that would make filling everything to zero easy (a la looping). You can call it with my_array.fill(0);.

Arrays and pointers in a template

I am attempting to write a template/class that has a few functions, but I'm running into what seems like a rather newbie problem. I have a simple insert function and a display values function, however whenever I attempt to display the value, I always receive what looks like a memory address(but I have no idea), but I would like to receive the value stored (in this particular example, the int 2). I'm not sure how to dereference that to a value, or if I'm just completely messing up. I know that vectors are a better alternative, however I need to use an array in this implementation - and honestly I would like to gain a more thorough understanding of the code and what's going on. Any help as to how to accomplish this task would be greatly appreciated.
Example Output (running the program in the same way every time):
003358C0
001A58C0
007158C0
Code:
#include <iostream>
using namespace std;
template <typename Comparable>
class Collection
{
public: Collection() {
currentSize = 0;
count = 0;
}
Comparable * values;
int currentSize; // internal counter for the number of elements stored
void insert(Comparable value) {
currentSize++;
// temparray below is used as a way to increase the size of the
// values array each time the insert function is called
Comparable * temparray = new Comparable[currentSize];
memcpy(temparray,values,sizeof values);
// Not sure if the commented section below is necessary,
// but either way it doesn't run the way I intended
temparray[currentSize/* * (sizeof Comparable) */] = value;
values = temparray;
}
void displayValues() {
for (int i = 0; i < currentSize; i++) {
cout << values[i] << endl;
}
}
};
int main()
{
Collection<int> test;
int inserter = 2;
test.insert(inserter);
test.displayValues();
cin.get();
return 0;
}
Well, if you insist, you can write and debug your own limited version of std::vector.
First, don't memcpy from an uninitialized pointer. Set values to new Comparable[0] in the constructor.
Second, memcpy the right number of bytes: (currentSize-1)*sizeof(Comparable).
Third, don't memcpy at all. That assumes that Comparable types can all be copied byte-by-byte, which is a severe limitation in C++. Instead:
EDIT: changed uninitialized_copy to copy:
std::copy(values, values + currentSize - 1, temparray);
Fourth, delete the old array when it's no longer in use:
delete [] values;
Fifth, unless the code is going to make very few insertions, expand the array by more than one. std::vector typically increases its size by a factor of 1.5.
Sixth, don't increment currentSize until the size changes. That will change all those currentSize-1s into currentSize, which is much less annoying. <g>
Seventh, an array of size N has indices from 0 to N-1, so the top element of the new array is at currentSize - 1, not currentSize.
Eighth, did I mention, you really should use std::vector.
This line is wrong:
memcpy(temparray,values,sizeof values);
The first time this line is run, the values pointer is uninitialized, so it will cause undefined behavior. Additionally, using sizeof values is wrong since that will always give the size of a pointer.
Another issue:
temparray[currentSize] = value;
This will also cause undefined bahavior because you have only allocated currentSize items in temparray, so you can only access indices 0 to currentSize-1.
There is also an error in your array access.
temparray[currentSize/* * (sizeof Comparable) */] = value;
Remember that arrays start at index zero. So for an array of length 1, you would set temparray[0] = value. Since you increment currentSize at the top of the insert function, you will need to do this instead:
temparray[currentSize-1] = value;

C++ Array of Objects

I have an array in a class that should hold some instances of other objects. The header file looks like this:
class Document {
private:
long arraysize;
long count;
Row* rows;
public:
Document();
~Document();
}
Then in the constructor I initialize the array like this:
this->rows = new Row[arraysize];
But for some reason this just sets rows to an instance of Row rather than an array of rows. How would I initialize an array of Row objects?
Both SharpTooth and Wok's answers are correct.
I would add that if you are already struggling at this level you may be better off using a std::vector instead of a built-in array in this case. The vector will handle growing and shrinking transparently.
This should work. One possible "error" would be an incorrect value for arraySize.
However you should better use a std::vector from the standard library for that purpose.
#include <vector>
class Document {
// ...
std::vector<Row> rows;
// ...
};
and in your constructor:
Document::Document() : rows(arraySize) { // ... }
or
Document::Document() { rows.assign(arraySize, Row()); }
If arraySize contains a reasonable value at that point you actually get an array. I guess you trust your debugger and the debugger only shows the 0th element (that's how debuggers treat pointers), so you think there's only one object behind that pointer.
For i in [0;arraysize[, *(this->rows+i) should be an instance of row.
What precisely makes you think that rows is only one element? Make certain that you arraysize isn't 1. If it is, you'll get an array of 1 element. Mind you, you must still call delete [] with an array of size 1.
Also, why is arraysize different than count? Using that terminology, you should be making an array of count elements and arraysize should be equal to sizeof(Row) * count.
Also, you specifically ask "How would I initialize an array of Row objects?". Do you mean allocate? If so, that's how you would do so. If you mean initialize, the default constructor of Row will be called on each element of the array when the array is allocated.