Why is this function segfaulting? - c++

The function is this:
Set::Set(Multinumber* tempArray[], int tempSize)
{
numElements = tempSize;
capacity = tempSize*2;
setArray = new Multinumber*[capacity];
for (int i=0; i<numElements; i++)
{
addElement(tempArray[i]);
}
}
The variable setArray is declared in my header to be of type Multinumber**
It segfaults whenever I call it with this:
Multinumber* carr[2];
carr[0]=c4;
carr[1]=c5;
Set setb(carr,2);
c4 and c5 are already declared pointers to objects of the proper type.
Any help would be much appreciated.
EDIT: Code below is addElement function (apologies for the indentation)
const Set Set::operator+(const Set& rhs) const
{
Set result;
int i=0, j=0;
while ((i < numElements) && (j < rhs.numElements))
{
Multinumber* toadd=new Multinumber;
toadd=*(setArray[i]) + *(rhs.setArray[j]);
result.addElement(toadd);
i++;
j++;
}
while ((i < numElements))
{
result.addElement(setArray[i]);
i++;
}
while ((j < rhs.numElements))
{
result.addElement(rhs.setArray[j]);
j++;
}
return result;
}
EDIT:
Based on numerous cout statements, error seems to be in this function:
bool Set::isFull()
{
return (numElements == capacity);
}
EDIT: Changed array indices, but still segfaults

Arrays use zero-based indexes, so setting carr[2] to anything in a two-length array is undefined behavior. You should be grateful it was a segfault. :-)
Try:
Multinumber* carr[2];
carr[0]=c4;
carr[1]=c5;
Set setb(carr,2);
That should take care of the segfault.

carr[1]=c4;
carr[2]=c5;
Shouldn't that be
carr[0]=c4;
carr[1]=c5;
?
Piece of advice: If you load this up in a debugger, such as gdb, it would have identified the culprit line and you would've seen your error very quickly.

Related

C++ Error - warning: comparison between signed and unsigned integer expressions [-Wsign-compare]

I'm trying to implement a sorting program of numbers, but am getting the following error:
I was able to compile and work the code on an online c++ compiler, but when I must run it via the terminal so after attempting to do so, it won't compile anymore. There's actually nothing wrong with the code itself, since they're just warnings. But I would like to know how to fix them all, please!
The errors come from these parts of my code:
void sort()
{
int i, j;
for (i = 0; i < storage.size()-1; i++)
{
for (j = 0; j < storage.size()-i-1; j++)
{
if (storage[j] > storage[j+1]) // swap the values
{
int temp = storage[j];
storage[j] = storage[j+1];
storage[j+1] = temp;
}
}
}
}
void print()
{
for(int i = 0; i < storage.size(); i++)
cout<<storage[i]<<" ";
cout<<endl;
}
vector<int> getList()
{
return storage;
}
void setList(vector<int> list)
{
storage = list;
}
};
void quickSort(int start, int end)
{
if (start < end)
{
int part = partition(start, end);
quickSort(start, part - 1);
quickSort(start + 1, end);
}
}
void sort()
{
quickSort(0, storage.size() - 1);
}
void print()
{
for(int i = 0; i < storage.size(); i++)
cout<<storage[i]<<" ";
cout<<endl;
}
Any help will be much appreciated. Thank you!
would like to know how to fix them all, please!
The diagnostic says that you are comparing numbers of different signedness. You can fix that by not comparing numbers of different signedness. You can go with using signed type on both sides or unsigned type on both sides.
Aside from the warning, storage.size()-1 is a dangerous operation unless you first enforce that the container is non-empty. If you subtract from a unsigned zero, you get a very large unsigned value. That is not bad by itself, but when you eventually use that large value as subscript, you get undefined behaviour. Simple solution to this is to add +1 to both sides of the comparison: i+1 < storage.size().

Accessing an object from a vector of object pointers

This is a bit code i'm having trouble with:
int pressedKey = event.getNativeKeyCode();
for (int i=0; i <= AllTriggerPads.size() ;i++) {
if (AllTriggerPads[i]->get_key() == pressedKey){
AllTriggerPads[i]->mBufferPlayerNode->start();
}
}
the get_key() is getting a EXC_BAD_ACCESS (Code=1, ...) Error.
I seem to have a referencing problem. I am using almost the same code in the mouseDown and the fileDrop function:
for (int i=0; i < AllTriggerPads.size() ; i++) {
if (AllTriggerPads[i]->mRect.contains(event.getPos())) {
AllTriggerPads[i]->mBufferPlayerNode->start();
}
}
This works fine!
Sooooo, i guess i am using the AllTriggerPads vector (of obj pointers) not correctly. So I CAN use AllTriggerPads[i]->mRect.contains(event.getPos())
but I CANT use AllTriggerPads[i]->get_key(). And I CANT access the value itself by AllTriggerPads[i]->key
I have tried it with AllTriggerPads.at(i) but then i get an out of range error which makes me wonder even more.
The AlltriggerPads was initialized with
vector<TriggerPad*> AllTriggerPads;
So how can I access the key member?
You are having an off-by-one error.
for (int i=0; i <= AllTriggerPads.size() ;i++)
replace with
for (int i=0; i < AllTriggerPads.size(); ++i)
(The ++ thing is irrelevant, it's just better practice to always use pre-increment)
You are trying to access an array element which doesn't exist. That's why it throws EXC_BAD_ACCESS. Change the for loop conditional to
for (int i = 0; i < AllTriggerPads.size(); ++i) {
if (AllTriggerPads[i]->get_key() == pressedKey) {
AllTriggerPads[i]->mBufferPlayerNode->start();
}
}
or if C++11 support is enabled, simplify it to
for (auto i : AllTriggerPads) {
if (i->get_key() == pressedKey) {
i->mBufferPlayerNode->start();
}
}

merge sort segmentation fault c++

I am trying to implement merge sort for my algorithm analysis class and every time I run it there is a segmentation fault. I think the problem is when i split the vector in the merge_sort function but I cannot find the problem. Help would be really appreciated guys.
template <typename T>
std::vector<int> merge(std::vector<T>& A,std::vector<T>& B)
{
int a_size = A.size();
int b_size = B.size();
std::vector<int> C(a_size+b_size,0);
//int *c = new int[b_size+a_size];
int i =0,j =0,k=0;
while(i < a_size && j < b_size)
{
if(A[i]<B[j])
{
C[k] = A[i];
k++;
i++;
}
else
{
C[k] = B[j];
k++;
j++;
if(i!=a_size)
{
for(;i<a_size;i++,k++)
{
//copy rest of a to c
C[k] = A[i];
}
}
if(j != b_size)
{
for(;j<b_size;k++,j++)
{
//copy the rest of b to c
C[k] = B[j];
}
}
}
}
return C;
}
// Merge sort implementation
template <typename T>
void merge_sort(std::vector<T>& vector)
{
// TODO implement merge sort
int vector_size = vector.size();
int big_vector_index = 0;
int half_size = (int)vector_size/2;
int remainder = vector_size%2;
std::vector<int> left(half_size,0);
std::vector<int> right(half_size+remainder,0);
for(int l = 0;big_vector_index<half_size;l++,big_vector_index++)
{
left[l] = vector[big_vector_index];
}
for(int m = 0;big_vector_index<vector_size;m++,big_vector_index++)
{
right[m] = vector[big_vector_index];
}
big_vector_index = 0;
merge_sort(left);
merge_sort(right);
vector = merge(left,right);
}
I took a look at your code, and the majority of it is correct from my testing. I don't want to do your coursework for you but maybe a couple of hints in the right direction will help.
For your original question about the segfault that you got, PaulMcKenzie, Jim Lewis, and Tahlil are right, merge_sort() needs a base condition (base case) to check whether or not the recursion should continue, so it doesn't run forever and/or until your computer runs out of memory (which is what is happening in your case). In general, any recursive function should have a base case.
Also, you should take a look at your merge function as well. It has all the parts of a correct merge function, but some parts of it run a bit earlier/more often than you want them too. I don't want to give too much away since it's for class, but if you fix the segfault problem and are still getting strange answers, take a look at it.

c++ BWAPI exception access violation

is there anybody using BWAPI who gets access violation error when accessing the Unit objects of the current game?
i am certain that the error is not in my code.. anyway.. is there anything i can do to avoid access violation?
i am getting this error sometimes at line with the comment bellow.. this code bellow execute many times and only sometimes i get the error..
int Squad::getSize() {
int no = 0;
for (int i = 0; i < (int) agents.size(); i++) {
BaseAgent* agent = agents.at(i);
if (agent != NULL && agent->isAlive() && agent->getUnit() != NULL && !agent->getUnit()->isBeingConstructed()) // this line
no++;
}
return no;
}
this is the code that I use to remove an BaseAgent from the vector.. analyze that and see if i can do it better:
void AgentManager::cleanup() {
//Step 2. Do the cleanup.
int cnt = 0;
int oldSize = (int)agents.size();
for (int i = 0; i < (int)agents.size(); i++) {
if (!agents.at(i)->isAlive()) {
delete agents.at(i);
agents.erase(agents.begin() + i);
cnt++;
i--;
}
}
int newSize = (int)agents.size();
}
the BaseAgent code is on this link
I would speculate that this line:
BaseAgent* agent = agents.at(i);
is returning some invalid pointer which is not set to 0.
Looking at your cleanup code, it looks a bit complicated. I would suggest
looping over the entire vector, deleting the dead elements and
setting the pointers to 0.
After the loop, use the erase-remove idiom to remove all NULL pointers from the vector.
step 1
for (unsigned int i = 0; i < agents.size(); ++i) {
if (!agents.at(i)->isAlive()) {
delete agents.at(i);
agents.at(i) = 0;
}
step 2
agents.erase(std::remove(agents.begin(), agents.end(), 0), agents.end());

Mergesort - std::bad_alloc thrown when trying to assign vector

Good afternoon ladies and gents. So, it is not my day for errors. Implementing Mergesort (not in-place) in C++, and I'm having real trouble with the code, with no idea why. The second-to-last line of the mergeSort() function assigns the result of the merge() to a vector of ints, result. This line (the actual allocation, not the function) throws a bad_alloc error, and I have no idea why.
The internet suggests that bad_alloc is mostly thrown due to out-of-memory errors, but this cannot be the case as the first time its called is on a vector of 500 ints, which should be nowhere near too much memory (what is that, like 2 Kb on a 32-bit int?). I assume I'm doing something silly and incorrect for C++, but I don't know what. I tried calling what() on the exception, but that just returns its name. The code:
vector<int> Sorting::mergeSort(vector<int> A) {
// If the length of A is 0 or 1, it is sorted.
if(A.size() < 2) return A;
// Find the mid-point of the list.
int midpoint = A.size() / 2;
// Declare the left/right vectors.
vector<int> left, right;
// Declare the return vector.
vector<int> result (A.size());
for(int i = 0; i < midpoint; ++i) {
left.push_back(A.at(i));
}
for(int i = midpoint; i < A.size(); ++i) {
right.push_back(A.at(i));
}
left = mergeSort(left);
right = mergeSort(right);
result = merge(left, right);
return result;
}
vector<int> merge(vector<int> left, vector<int> right) {
vector<int> result;
while(left.size() > 0 && right.size() > 0) {
if(left.front() <= right.front()) {
result.push_back(left.front());
left.erase(left.begin());
} else {
result.push_back(right.front());
right.erase(right.begin());
}
}
if(left.size() > 0) {
for(int i = 0; i < left.size(); ++i) {
result.push_back(left.at(i));
}
} else {
for(int i = 0; i < right.size(); ++i) {
result.push_back(right.at(i));
}
}
}
If I re-write the merge function to just take a reference to result and edit it during the function, it works fine, but I wanted to keep the code as close as possible to the 'standard' psuedo-code given for merge-sort.
I appreciate any help, thanks.
In the Merge function, vector<int> result is not being returned.