Print the same array, it is different in different functions, why? - c++

I'm writing a program to solve the shortest path between two points in a circuit wiring. I use the BFS(breadth search first) method. I save the path in the path array, but I find that the coordinates of the last point in the path are not what I want (sometimes the value is correct and sometimes not).So, I printed out the path array in the findPath function, which was correct, but not correct in the main function.Why?
What's wrong with my description?I am not a native English speaker and my English is not particularly good.Please point out if what I said is not clear.
English retrieval ability is still poor, I do not know if this problem is repeated.If repeated please forgive me!
Thank you very much!
#include<iostream>
#include <iomanip>
#include<queue>
using namespace std;
const int M = 9;
const int MAXLEN = 30;
class Point
{
public:
int x;
int y;
};
//The increments in the x and y direction,
// in the order of up, right, down, and left
int dx[4] = {0,1,0,-1};
int dy[4] = {-1,0,1,0};
void findPath(int G[][M],Point start,Point finish,int& pathLen,Point path[])
{
//Find the shortest path from start to finish and its length, pathLen
if(start.x == finish.x && start.y == finish.y) //Two overlapping
{
pathLen = 0;
return ;
}
Point cur,next;
G[start.x][start.y] = 1; //Start of blockade
queue<int> qx,qy; //Coordinates the queue
qx.push(start.x); qy.push(start.y); //The starting point enters the queue
while(!qx.empty())
{
cur.x = qx.front(); qx.pop(); // 'cur' stands for current position
cur.y = qy.front(); qy.pop();
for(int i = 0;i < 4; i++)
{
next.x = cur.x + dx[i]; next.y = cur.y + dy[i]; // next is the next position
if(!G[next.x][next.y]) //The location is not marked
{
G[next.x][next.y] = G[cur.x][cur.y] + 1;
if(next.x == finish.x && next.y == finish.y) //Finish line
{
break;
}
qx.push(next.x);
qy.push(next.y);
}
}
if(next.x == finish.x && next.y == finish.y) break; //Finish line
}
//Structural path
pathLen = G[finish.x][finish.y];
cur = finish;
for(int i = pathLen-1; i >= 0; i--)
{
path[i] = cur; //Record current position
for(int j = 0; j < 4; j++) //Look for the previous position
{
next.x = cur.x + dx[j];
next.y = cur.y + dy[j];
if(G[next.x][next.y] > -1 && G[next.x][next.y] < G[cur.x][cur.y])
{
break;
}
}
cout<<"path["<<i<<"]="<<path[i].x<<","<<path[i].y<<endl;
cur = next; //Move to current position
}
}
int main()
{
int G[M][M]; //Grid map
Point start,finish; // The starting point and end point
int pathLen; //Shortest path length
for(int i = 0; i < M; i++) //Initializes the outer fence as -1
{
G[0][i] = G[M-1][i] = G[i][0] = G[i][M-1] = -1;
}
for(int i = 1; i < M-1; i++) //Initialize the region in the grid to 0
{
for(int j = 1; j < M-1; j++)
G[i][j] = 0;
}
G[5][1] = -1; G[6][1] = -1; G[6][2] = -1; G[6][3] = -1; G[7][1] = -1;
G[7][2] = -1; G[7][3] = -1; G[1][3] = -1; G[2][3] = -1; G[2][4] = -1;
G[3][5] = -1; G[4][4] = -1; G[4][5] = -1; G[5][5] = -1; // Inside a wall
for(int i = 0; i < M; i++) //Initial time map
{
for(int j = 0; j < M; j++)
{
cout<<setw(4)<<G[i][j];
}
cout<<endl;
}
start.x = 3; start.y = 2; finish.x = 4; finish.y = 6;
Point *path = new Point[M];
findPath(G,start,finish,pathLen,path);
for(int i = 0; i < M; i++) //Complete time map
{
for(int j = 0; j < M; j++)
{
cout<<setw(4)<<G[i][j];
}
cout<<endl;
}
for(int i = 0; i < pathLen; i++)
{
cout<<"path["<<i<<"]="<<path[i].x<<","<<path[i].y<<endl;
}
return 0;
}
output:
As you can see in the figure below, the path[9] output in the findPath function is different from that in the main function.
Sometimes the results are right

Valgrind says:
==27791== Invalid read of size 4
==27791== at 0x401B7B: main (delme.cpp:113)
==27791== Address 0x4daf108 is 0 bytes after a block of size 72 alloc'd
==27791== at 0x4839593: operator new[](unsigned long) (vg_replace_malloc.c:433)
==27791== by 0x401A03: main (delme.cpp:101)
==27791==
==27791== Invalid read of size 4
==27791== at 0x401BA6: main (delme.cpp:113)
==27791== Address 0x4daf10c is 4 bytes after a block of size 72 alloc'd
==27791== at 0x4839593: operator new[](unsigned long) (vg_replace_malloc.c:433)
==27791== by 0x401A03: main (delme.cpp:101)
you are accessing erroneous bytes (outside your allocated memory)
the line reported by valgrind is
cout<<"path["<<i<<"]="<<path[i].x<<","<<path[i].y<<endl;

Related

C++ code runs sometimes but other times it either hangs or throws exceptions

I wrote a C++ program that merges sorted sub-arrays, but my issue is that when I run the code using Visual Studio it runs perfectly fine sometimes, but other times it doesn't (I'd say it runs without issues ~40% of the time), when it doesn't run as intended it either hangs at a certain point or it throws exceptions, sometimes the exception is heap corruption, other times it just says that (myapp).exe has triggered a breakpoint. Also, another issue I'm having is when I try to delete my dynamic array I get an error, the error I get is at the end of the post and the dynamic array that I'm trying to delete is commented out at the end of the MergeSubArrays code snippet.
void MergeSubArrays(int arr[], int size, int R) {
int lP, rP, lLimit, rLimit, p = 0, c = 0, rC = R;
int* temp = new int[size];
bool breakOut = false;
while (R < size) {
lP = 0, rP = R, lLimit = R, rLimit = R * 2;
while (p < size) {
while (lP < lLimit && rP < rLimit) {
if (arr[lP] < arr[rP]) {
temp[p] = arr[lP];
p++;
lP++;
}
else {
temp[p] = arr[rP];
p++;
rP++;
}
}
while (lP < lLimit) {
temp[p] = arr[lP];
p++;
lP++;
}
while (rP < rLimit) {
temp[p] = arr[rP];
p++;
rP++;
}
for (;c < p;c++) {
arr[c] = temp[c];
}
if ((rLimit + 2 * R) <= size) {
rLimit += (2 * R);
lLimit += (2 * R);
lP += R; rP += R;
}
else {
break;
breakOut = true;
}
if (breakOut) break;
}
if (breakOut) break;
p = 0; c = 0; R += R;
}
if (rLimit < size) {
p = 0; c = 0; lP = 0;
while (lP < rLimit && rP < size) {
if (arr[lP] < arr[rP]) {
temp[p] = arr[lP];
p++;
lP++;
}
else {
temp[p] = arr[rP];
p++;
rP++;
}
while (lP < rLimit) {
temp[p] = arr[lP];
p++;
lP++;
}
while (rP < size) {
temp[p] = arr[rP];
p++;
rP++;
}
for (;c < size;c++) {
arr[c] = temp[c];
}
}
}
/*delete[] temp; <-- this results in a breakpoint with a code snippet that I'll show at the end of
the post*/
}
void SortIntoSubArrays(int arr[], int begin, int end) {
if (begin < end) {
int j, key, pos;
for (int i = begin;i < end;i++) {
j = i - 1;
key = arr[i];
pos = BinarySearch(arr, key, begin, j);
while (j >= pos) {
arr[j + 1] = arr[j];
j--;
}
arr[j + 1] = key;
}
}
}
int main() {
int size = 15;
int* arr = new int[size];
arr[0] = 5; arr[1] = 2; arr[2] = 10; arr[3] = 1; arr[4] = 8; arr[5] = 3; arr[6] = 12; arr[7] = 4;
arr[8] = 7; arr[9] = 20; arr[10] = 15; arr[11] = 17; arr[12] = 5; arr[13] = 40; arr[14] = 45;
int R = 3;
for (int i = 0; i < size;i += R) {
if (i + R <= size) InsertionSort2(arr, i, i + R);
else SortIntoSubArrays(arr, i, size);
}
MergeSubArrays(arr, 15, R);
for (int i = 0;i < size;i++) {
cout << arr[i] << endl;
}
}
This is what I get when I try to add delete[] temp; in the MergeSubArrays function:
CRT_SECURITYCRITICAL_ATTRIBUTE
void __CRTDECL operator delete(void* const block) noexcept
{
#ifdef _DEBUG
_free_dbg(block, _UNKNOWN_BLOCK);
#else
free(block);
#endif
}
edit: Fixed the issue, thanks for the help!
Often when it may run sometimes and not other can be attributed to a memory leak. Sometimes you may get lucky and the leak wont corrupt other data but often it does curropt other data.
Try using a prebuilt list class from the std library with error catching and see what error it throughs and then fix it. One last thing if that does not work check compiler options as that may disable the error checking
Edit: most licky cause is an invalid write not a leak. Thanks guy in comments.

equal jump between numbers in two arrays

I want to compare two arrays. One of them is a subset of the other one. I want my function to return the minimum and equal gap between the numbers of the first subset array in the other array.
For example if I have
arr1 = 2,1,4,2,8,3
sub= 1,2,3
I want my function to return 1 because the mimimum gap between all this numbers are 1.
arr1 = 2,1,5,2,1,2,3
sub= 1,2,3
I want my function to return 0 because the mimimum gap between 1,2,3 in arr1 is 0
Here is the code I am trying to do: My code always return 0 can you help me understand why, and how can I solve this.
int gap(int* arr, int* sub, int sizeArr, int sizeSub)
{
int index = 0; int gap = 0; bool flag = true;
int i = -1;
for (int jump = 1; jump < sizeArr / sizeSub; jump++)
{
index = 0;
for (i = i +1; i < sizeArr; i++)
{
if (sub[index] == arr[i])
{
for (int j = i + jump, index = 1; j < sizeArr; j = j + jump, index++)
{
if (arr[j] != sub[index]) { flag = false; break; }
else if (arr[j] == sub[index] && index == sizeSub) { flag = true; break; }
}
}
if (!flag) { break; }
else { gap = jump; break; }
}
}
return gap;
}
You initially took gap equally 0 but i think more suit to not store gap
and start iterate jump from 0. And return jump immediately after you found that it is suit.
Also i think that store index in such manner as you it is bad idea, because you code return wrong answer on
int a[] = { 2,1,4,4,2,8,5,3 };
int s[] = { 1,2,3 };
I think you should declare variable as soon as possible, otherwise there will be undesirable side effects.
So you code can be rewritten as
int gap(int *arr, int *sub, int sizeArr, int sizeSub)
{
for (int jump = 0; 1 + (jump + 1) * (sizeSub - 1) <= sizeArr; jump++) {
for (int start_index = 0; start_index + (jump + 1) * (sizeSub - 1) < sizeArr; start_index++) {
bool flag = true;
for (int index = 0; index < sizeSub; ++index) {
if (arr[start_index + index * (jump + 1)] != sub[index]) {
flag = false;
break;
}
}
if (flag) {
return jump;
}
}
}
return -1; //or some value that indicate that there is no answer
}

Bitwise integer concationation

For some background, I'm trying to write a system to pass packets of integers for the purpose of building a maze using a boolean toggle to decide whether two nodes should have a wall between them, currently my maze handles 480 walls, therefore I don't want to send a packet with a single item, but rather split it into an array of integers (length 8) thus giving me 480/8 objects to send.
const int wallRows = mazeSize / 8;
int temp = NULL;
int temp2 = NULL;
int current = NULL;
int concatCount = 0;
int* walls = new int[wallRows];
int wallIndex = 0;
for (int i = 0; i < mazeSize; i++) {
current = temp2;
//ensure my ints have only 8 bytes
if (concatCount >= 7) {
//allocate a full int to the array
walls[wallIndex] = temp;
//clear the int
temp = NULL;
//move to the next array pos
wallIndex++;
//restart the int count
concatCount = 0;
}
if (maze->allEdges[i]._iswall) {
//append a 1 to the int
temp = 0b1;
}
else {
//append a 0 to the int
temp = 0b0;
}
//increment the int count
current = (temp2 << 1) | temp;
concatCount++;
}
This is what I have currently built, my idea was to start with an int, pass it the int based on the return of the bool "_isWall" and bit shift the result onto the end of the int.
When the int reaches capacity, iterate to the next int in the array and begin again until the maze's walls have populated the array.
Edit: lack of clarity on what I was asking.
My bitwise operation does not appear to actually allocate multiple bits to the same integer, where am I going wrong?
Use val | (1UL << temp2), and not temp2 << 1 to set the bits. Later you can use bitwise & operator to see if the bit is set. You must initialize the whole byte to zero and set the bit only if the value is true. Here is an example:
int main(void)
{
//assign random values for testing
int wallinfo[480];
for(int i = 0; i < 480; i++)
wallinfo[i] = !!(rand() % 2);
//copy to the values to compress
unsigned char compress[60] = { 0 };
for(int i = 0; i < 60; i++)
for(int j = 0; j < 8; j++)
if(wallinfo[i * 8 + j])
compress[i] |= 1UL << j;
//decompress to get back wallinfo
int decompress[480];
for(int i = 0; i < 60; i++)
for(int j = 0; j < 8; j++)
decompress[i * 8 + j] = !!(compress[i] & (1UL << j));
//wallinfo should match decompress
if(memcmp(wallinfo, decompress, 480) == 0)
printf("success\n");
else
printf("failed\n");
return 0;
}

Huffman coding c++

So I am working on Huffman coding for a project. However, my code just doesn't work. When i ran it on visual studio, it didn't give me an error. What I was trying to do is to read a file and put all of them into a string. And get the frequency for each character in that string. But I think when the file got a little bit large, it seems like my code is running in a infinite loop. Can anyone explain anything to me? By the way, I had a sorted function that I used to sort a vector of node* by their frequency.
ifstream infile;
infile.open(filename);
string q;
string line;
while (getline(infile, line))
{
q += line;
}
char y;
int count = 0;
int check = 0;
for (int i = 0; i < q.size(); i++) //if the string gets big, it seems to become an infinite loop in here
{
y = q[i];
for (int x = i - 1; x > 0; x--) //make sure not counting the same char
{
if (y == q[x])
{
check++;
}
}
if (check == 0)
{
for (int i = 0; i < q.size(); i++)
{
if (q[i] == y)
{
count++;
}
}
node*x = new node;
x->char1 = y; //my node have char
x->freq = count; //my node has frequency
list1.push_back(x);
}
count = 0;
check = 0;
}
sort(list1.begin(), list1.end(), sorter); //sort them from small to big
while (list1.size() > 1)
{
node*left = list1[0];
node*right = list1[1];
list1.erase(list1.begin(), list1.begin() + 2);
double sum = left->freq + right->freq;
node* x = new node;
x->freq = sum;
x->left = left;
x->right = right;
list1.push_back(x);
sort(list1.begin(), list1.end(), sorter);
}
list1.clear();
return true;
The following is my sort function
static struct {
bool operator()(NodeInterface* a, NodeInterface* b) {
if (a->getFrequency() == b->getFrequency()) {//if the frequencies are even,
if (b->getCharacter() == '\0') return false;
if (a->getCharacter() != '\0') {
return (int)a->getCharacter() < (int)b->getCharacter();
}
return false;
}
return a->getFrequency() < b->getFrequency();
}
} sorter;
I see two major problems.
You have a for loop inside a for loop both initializing and using int i
Change the variable name of the inner loop.
for (int i = 0; i < q.size(); i++) //if the string gets big, it seems to become an infinite loop in here
.
.
if (check == 0)
{
for (int i = 0; i < q.size(); i++) //Change this to int j for example
{
.
.
And the Sorter struct. I would rewrite it as this.
static struct {
bool operator()(NodeInterface* a, NodeInterface* b) {
if (a->getFrequency() == b->getFrequency()) {//if the frequencies are even,
if (b->getCharacter() == '\0') return false;
if (a->getCharacter() == '\0') return true;
return (int)a->getCharacter() < (int)b->getCharacter();
}
return a->getFrequency() < b->getFrequency();
}
} sorter;
A few suggestions for your for loop:
for (int i = 0; i < q.size(); i++) //if the string gets big, it seems to become an infinite loop in here
{
y = q[i];
//You can avoid this entire loop by using a structure like map
for (int x = i - 1; x > 0; x--) //make sure not counting the same char
{
if (y == q[x])
{
check++;
//break; //if you use a loop, break it once you find the character.
}
}
if (check == 0)
{
for (int j = 0; j < q.size(); j++)//Renamed variable + you can start this loop from j = i as you know there is no occurrence of y before that.
{
if (q[i] == y)
{
count++;
}
}
node*x = new node;
x->char1 = y; //my node have char
x->freq = count; //my node has frequency
list1.push_back(x);
}
count = 0;
check = 0;
}

Checking for overlapping characters in a wordsearch game

I am developing a wordsearch generator to learn c++ better and I am stuck on preventing non-overlapping words from overlapping, such as a side-to-side word writing over a letter in a top-down word. Here is the code snippet:
else if (random_choice == 1 && random_word.size() <= 10-j && words_vector.size() != 0) {
flag = true;
for (int x = 0; x < random_word.size(); x++) {
if (wordsearch[i][j+x] != '0') {
flag = false;
break;
}
}
if (flag = true) {
for (int x = 0; x < random_word.size(); x++) {
wordsearch[i][j] = random_word[x];
j += 1;
}
j -= 1;
words_found_vector.insert(words_found_vector.begin(),words_vector[random_word_number]);
//words_vector.erase(words_vector.begin()+random_word_number);
}
else {
wordsearch[i][j] = '1';
}
}
What I have done was create a two dimensional array [10][11] filled with the 0 (zero) character so when I iterate through it all spaces are filled with 0 except for the 11th space in each line with a newline character to make a 10X10 grid. In my else if loop, the first part already has a word chosen and it tests if the word will fit in its proper space by checking if a 0 is present. If it runs into a non-zero character (such as if it runs into a letter from a top-down or diagonal word) the inner loop terminates, sets the boolean flag, and inputs a 1 (or any random letter) instead of the whole word. What happens is that the whole word is inserted anyways and overwrites one letter from the top down word. What am I doing wrong? Here is the rest of the code:
#include <iostream>
#include <cstdlib>
#include <time.h>
#include <vector>
#include <algorithm>
using namespace std;
int main() {
srand(time(NULL));
const char* const a_to_z = "ABCDEFGHIJKLMNOPQRSTUVWXYZ" ;
int random_char;
char wordsearch [10][11] = {0};
bool flag;
string words_array[] = {"CAT", "HELLO", "GOODBYE", "DOG", "BAT", "NEW", "SAY", "MAY", "DAY", "HAY"};
vector<string> words_vector (words_array, words_array + sizeof(words_array) / sizeof(string));
string words_found_array[] = {};
vector<string> words_found_vector (words_found_array, words_found_array + sizeof(words_found_array) / sizeof(string));
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 11; j++) {
int random_choice = rand() % 5;
int random_word_number = rand() % words_vector.size();
string random_word = words_vector[random_word_number];
if (j == 10) {
wordsearch[i][j] = '\n';
}
else if (random_choice == 1 && random_word.size() <= 10-j && words_vector.size() != 0) {
flag = true;
for (int x = 0; x < random_word.size(); x++) {
if (wordsearch[i][j+x] != '0') {
flag = false;
break;
}
}
if (flag = true) {
for (int x = 0; x < random_word.size(); x++) {
wordsearch[i][j] = random_word[x];
j += 1;
}
j -= 1;
words_found_vector.insert(words_found_vector.begin(),words_vector[random_word_number]);
//words_vector.erase(words_vector.begin()+random_word_number);
}
else {
wordsearch[i][j] = '1';
}
}
else if (random_choice == 2 && random_word.size() <= 10-i && words_vector.size() != 0) {
int temp_i = i;
flag = true;
for (int x = 0; x < random_word.size(); x++) {
if (wordsearch[i+x][j] != '0') {
flag = false;
break;
}
}
if (flag = true) {
for (int x = 0; x < random_word.size(); x++) {
wordsearch[i][j] = random_word[x];
i += 1;
}
i = temp_i;
words_found_vector.insert(words_found_vector.begin(),words_vector[random_word_number]);
//words_vector.erase(words_vector.begin()+random_word_number);
}
else {
wordsearch[i][j] = '1';
}
}
else {
int random_char = rand() % 26 + 0;
wordsearch[i][j] = a_to_z[random_char];
}
}
}
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 11; j++) {
cout<<wordsearch[i][j];
}
}
cout<<"Your words are:"<<endl;
for (int x = 0; x < words_found_vector.size(); x++) {
cout<<words_found_vector[x]<<endl;
}
}
One more thing:
//words_vector.erase(words_vector.begin()+random_word_number);
crashes my program. I think it is a scoping issue with this:
int random_choice = rand() % 5;
int random_word_number = rand() % words_vector.size();
string random_word = words_vector[random_word_number];
What I want to do is eventually have the user give me a list of words they want to search for and this function chooses some of them and presents it to the user when playing the game. This not functioning correctly also causes duplicates to appear in the crossword and words-to-find-list.
Thank you for your help!
You have this error twice in your code:
if (flag = true)
That is not a condition, it's an assignment. It assigns true to flag, and the if-block will always execute. You need to make it a comparison condition by using ==
if (flag == true)
A more common way to write that in C++ would be just
if (flag)