// Take last element from deck and add to dealer's hand
// Update current elements after
//Ensure the deck still has cards
if (deck.currentElements == 0) {
getNewDeck(deck);
shuffleDeck(deck);
}
deck.currentElements -= 1;
dealerCards.currentElements += 1;
dealerCards.Cards[dealerCards.currentElements] = deck.Cards[deck.currentElements];
// Update the deck array by decreasing size
// hence used cards are removed
Card* temp = deck.Cards;
deck.Cards = new Card[deck.currentElements];
for (int i = 0; i < deck.currentElements; i++) {
deck.Cards[i] = temp[i];
}
// Delete memory associated with temp
delete[] temp;
Hi, i am getting the following error on "deck.Cards[i] = temp[i];": C6385 Reading invalid data from 'deck.cards': the readable size is '(unsigned int)*64+4 bytes', but '128 bytes' may be used.
What am I doing wrong, and how can I fix this? The problem came up when I added the if statement seen at the top. Is there a chance that this could simply be a false warning? I am using visual studios
dealerCards.Cards[dealerCards.currentElements] will not be assigned for dealerCards.Cards[0]; there will be a hole.
--deck.currentElements;
dealerCards.Cards[dealerCards.currentElements] = deck.Cards[deck.currentElements];
++dealerCards.currentElements;
This assumes that a valid index is in 0 .. (currentElements-1).
The error however is on the deck, but is probably of very similar code elsewhere.
As C level code is very basic (arrays) and error prone, better switch to higher types like vector.
Related
This is from a homework assignment that was already turned in. The program is a card game that plays correctly but seg faults when the game is over. I can trace the core dump to my delete [] playerArr, but I think the real problem is in how I'm declaring my playerArr.
I have a constructor, copy, overloaded operator and destructor in my .h file that works well with other programs so I think my problem is in main. I've looked at several other questions here and on google and haven't found one quite like this. Here are the code snippets:
struct Player
{
int currentHand; //current number of cards in given player's hand
Queue hand; //queue to store player's hand
};
in main I allocate an array of structs, I think this is my problem. I've trial and errored a variety of approaches but this one allows my program to compile and my game to play as designed:
//allocate array of Player structs
Player *playerArr = new Player[numPlayers];
for (int i = 1; i <= numPlayers; i++)
playerArr[i].currentHand = 0;
//enqueue playerArr.hand
deal(playerArr, deck, numPlayers, currentDeck);
this is the sequence I use to clean up before deleting, the core dumps after cout:
//exit do-while loop and end game
}
while (playerArr[currentPlayer - 1].currentHand != 0);
for (int i = 1; i < numPlayers; i++)
{
while (playerArr[i].currentHand > 0)
{
playerArr[i].hand.dequeue(catchQ);
playerArr[i].currentHand--;
}
}
//empty all deck/discard stacks
while (!deck.isEmpty())
deck.pop(catchPop);
while (!discard.isEmpty())
discard.pop(catchPop);
//reset hand/deck counters to defaults
catchQ = 0;
catchPop = 0;
currentDeck = 52;
currentPlayer = 1;
numPlayers = 2;
cout << "\n\n\n\t Good Game!" << endl << endl;
//free dynamic memory
delete [] playerArr;
It's too late for me to change my grade on this program and with finals week I don't have time to visit my prof during office hours so if someone has a solution for me I can learn from this mistake and move on.
Thank you
One probable cause of the problem is that you forget that array-indexes are zero-based.
An array of numPlayers elements will have indexes from 0 to numPlayers - 1 (inclusive).
The first loop you show doesn't use that, instead if goes from 1 to numPlayers, leading you to index the allocated memory out of bounds which leads to undefined behavior.
I've run into this error before, but the circumstances baffle me as I have run nearly this exact set of functions without having this issue.
Let me break it down:
The error is being caused by the resize() private member function of a custom priority queue I am working on. It is all centered around de-allocating the pointer to the old queue array. Before I explain any further, let me list the handful of relatively small functions I've isolated the problem to.
void unfairQ::enqueue(int val)
{
if (isFull())
resize();
numElements++;
ageCount++;
heapArr[numElements].data = val;
heapArr[numElements].age = 1;
heapArr[numElements].priority = heapArr[numElements].data;
heapifyUp(numElements);
if (ageCount == 100) {
heapSort();
ageCount = 0;
}
return;
}
bool unfairQ::isFull()
{
return (numElements == capacity);
}
void unfairQ::resize()
{
int newCap = (capacity * 1.5);
queueNode *tempHeap = new queueNode[newCap];
for (int i = 1; i <= numElements; i++) {
tempHeap[i].data = heapArr[i].data;
tempHeap[i].age = heapArr[i].age;
tempHeap[i].priority = heapArr[i].priority;
}
// delete [] heapArr;
capacity = newCap;
heapArr = tempHeap;
return;
}
The commented out line in the resize function is the one causing problems. If I do delete the pointer to the array I get the "double free" error, however if I remove that line I get a "free(): invalid next size (normal):" if I enqueue enough values to require a second resize().
Please let me know if you need any more information or if I need to clarify anything.
You seem to be using your array with indexes starting from 1, c++ uses indexes starting from 0. This can cause a buffer overflow.
For example:
If capacity is currently 5 (so heapArray can have 5 entries) andnumElementsis currently 4, yourisFullwill returnfalse(correctly), however yourenqueuecode then incrementsnumElements(from 4 to 5) and attempts to write toheapArray[5]` which is out of bounds and may overwrite some other memory.
Solution: start your indexes from 0, e.g. in the enqueue function, increment numElements after you write the data heapArray[numElements]
I found the problem, while I was referencing/incrementing/decrementing all the indices correctly and calling the appropriate functions at the appropriate times, I was operating under the notion that I was working with indices 1-size, but in the constructor (something I hadn't glanced at for a while) I'd initialized numElements as 0 which broke the whole gosh darned thing.
Fixed that and now everything is hunky dory!
Thanks for the help guys.
I am trying to insert data into a leaf node (an array) of a B-Tree. Here is the code I have so far:
void LeafNode::insertCorrectPosLeaf(int num)
{
for (int pos=count; pos>=0; pos--) // goes through values in leaf node
{
if (num < values[pos-1]) // if inserting num < previous value in leaf node
{continue;} // conitnue searching for correct place
else // if inserting num >= previous value in leaf node
{
values[pos] = num; // inserts in position
break;
}
}
count++;
} // insertCorrectPos()
Before the line values[pos] = num, I think need to write some code that shifts the existing data instead of overwriting it. I am trying to use memmove but have a question about it. Its third parameter is the number of bytes to copy. If I am moving a single int on a 64 bit machine, does this mean I would put a "4" here? If I am going about this completely wrong any any help would be greatly appreciated. Thanks
The easiest way (and probably the most efficient) would be to use one of the standard libraries predefined structures to implement "values". I suggest either list or vector. This is because both list and vector has an insert function that does it for you. I suggest the vector class specifically is because it has the same kind of interface that an array has. However, if you want to optimize for speed of this action specifically, then I would suggest the list class because of the way it is implemented.
If you would rather to it the hard way, then here goes...
First, you need to make sure that you have the space to work in. You can either allocate dynamically:
int *values = new int[size];
or statically
int values[MAX_SIZE];
If you allocate statically, then you need to make sure that MAX_SIZE is some gigantic value that you will never ever exceed. Furthermore, you need to check the actual size of the array against the amount of allocated space every time you add an element.
if (size < MAX_SIZE-1)
{
// add an element
size++;
}
If you allocate dynamically, then you need to reallocate the whole array every time you add an element.
int *temp = new int[size+1];
for (int i = 0; i < size; i++)
temp[i] = values[i];
delete [] values;
values = temp;
temp = NULL;
// add the element
size++;
When you insert a new value, you need to shift every value over.
int temp = 0;
for (i = 0; i < size+1; i++)
{
if (values[i] > num || i == size)
{
temp = values[i];
values[i] = num;
num = temp;
}
}
Keep in mind that this is not at all optimized. A truly magical implementation would combine the two allocation strategies by dynamically allocating more space than you need, then growing the array by blocks when you run out of space. This is exactly what the vector implementation does.
The list implementation uses a linked list which has O(1) time for inserting a value because of it's structure. However, it is much less space inefficient and has O(n) time for accessing an element at location n.
Also, this code was written on the fly... be careful when using it. There might be a weird edge case that I am missing in the last code segment.
Cheers!
Ned
I'm running CodeBlocks on the MingW compiler in an XP virtual machine. I wrote in some simple code, accessible at cl1p , which answers the algorithm question at CodeChef (Well it only answers it partly, as I have not yet included the loop for multiple test cases.
However, my problem is, that while running it in debug mode, it gives the correct output of 5, for the input:
3
1
2 1
1 2 3
However, when I build and run it, it gives the absurd, huge output 131078, what seems like garbage to me. I do not understand how the hell this is happening, but am guessing it's something to do with the dynamic memory allocation. What's the problem here, and how can I fix it? I even ran it through the online compiler at BotSkool, and it worked fine. After adding the loop for test cases, the code even worked correctly on CodeChef!
#include <iostream>
using namespace std;
int main()
{
// Take In number of rows
int numofrows;
cin >> numofrows;
// Input Only item in first row
int * prevrow;
prevrow = new int[1];
cin >> prevrow[0];
// For every other row
for (int currownum = 1; currownum < numofrows; currownum++)
{
// Declare an array for that row's max values
int * currow;
currow = new int[currownum+1];
int curnum;
cin >> curnum;
// If its the first element, max is prevmax + current input
currow[0] = prevrow[0] + curnum;
// for every element
int i = 1;
for (; i <= currownum; i++)
{
cin >> curnum;
// if its not the first element, check whether prevmax or prev-1max is greater. Add to current input
int max = (prevrow[i] > prevrow[i-1]) ? prevrow[i] : prevrow[i-1];
// save as currmax.
currow[i] = max + curnum;
}
// save entire array in prev
prevrow = new int[i+1];
prevrow = currow;
}
// get highest element of array
int ans = 0;
for (int j=0; j<numofrows; j++)
{
if (prevrow[j] > ans)
{
ans = prevrow[j];
}
}
cout << ans;
}
Run the code through Valgrind on a Linux machine and you'll be amazed at how many places your code is leaking memory.
If you are taking the hard road of managing your memory, do it well and 'delete' all the new-allocated memory before allocating more.
If, on the other hand, you prefer the easy road, use a std::vector and forget about memory management.
For one thing, this:
//save entire array in prev
prevrow = new int [i+1];
prevrow = currow;
copies the pointer, not the whole array.
In your loop, you have this line
int max = (prevrow[i]>prevrow[i-1])?prevrow[i]:prevrow[i-1];
On the first iteration of the main loop, when currownum == 1, the loop containing this line will be entered, as i is initialized to 1. But on the first iteration, prevrow only has one element and this line tries to access prevrow[1]. In a debug build, the memory simply gets initialized to zero, but in a normal build, you get some garbage value that just happened to be in the memory, leading to the result you see.
Pretty much always, when you get garbage values in a normal build, but everything is fine in a debug build, you are accessing some uninitialized memory.
Also, your program is leaking memory like crazy. For instance, you don't need to assign any result of new inside the loop to prevrow because right after that you change prevrow to point to another block of allocated memory. Also, you should call delete for any memory that you are no longer using.
Strange programming problems as of now..As you can see below i have assigned intFrontPtr to point to the first cell in the array. And intBackPtr to point to the last cell in the array...:
bool quack::popFront( int &popFront )
{
//items[count-1].n = { 9,4,3,2,1,0 };
nPopFront = items[0].n;
if ( count >= maxSize ) return false;
else
{
items[0].n = nPopFront;
intFrontPtr = &items[0].n;
intBackPtr = &items[count-1].n;
}
for (int temp; intFrontPtr < intBackPtr ;)
{
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
--count;
return true;
}
Its just my implementation of a cross between a queue and a stack..PopFront is a public method of the class object quack..The items is a private struct type 'item', it is within the quack.h. It has one member, 'int n'..But, that is irrelevent.
the comment in the code is the contents of my integer array, 'items'.
I am trying to Pop elements off the front of my array. WHat im thinking is that after i get the first item, i'll just incrememnt the frontPtr and transfer the item i got previously to the frontPtr i incremented!...
I cannot, for any reason, use a + or - shift by 1 or the use of stls, boosts, std's and the like..
Can someone help me with my homework assignment?
My suggestion are :
1). Put statement --count where it keeps object's state valid on exceptional condition.
2). clear your concepts of pointers which will help you a lot.
Generally, I would not recommend using an array if you want to pop items off the front. You would be much better off using a linked list, or some other structure which will allow you to remove items in O(1) time. It will be much easier to remove (pop) items this way.
As for your current code, I really can't comment without a better idea of what your class looks like. Please post the class definition at least so we can tell what all your variables are referring to, and what you're code is actually doing.
There are quite a few problems. But I believe your major one is this loop:
for (int temp; intFrontPtr < intBackPtr ;)
{
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
}
It looks to me like you are trying to shift all your items down. Since this is homework, I'm not going to give you the answer but I'll give you some hints to help debug this.
What you want to do is examine your items array at the beginning and end of the loop.
for (int temp; intFrontPtr < intBackPtr ;)
{
// whats does array look like here
intFrontPtr++;
temp = *intFrontPtr;
*intFrontPtr = temp;
// and what does array look like here
}
If you don't have experience with a debugger, add a function call that will dump your array.