Printing int **x in GDB - c++

I have an array (called board) of pointers which point to array.
I want to print it in normal way (which is pretty hard in GDB).
int col = 64, row = 2;
int **board = new int*[col];
for(int i = 0; i < col; i++)
board[i] = new int[row];
I have tried following commands:
p *array#len (the problem is it prints in hexadecimal values not as integer)
x/100w array (It scrolls so much down that i cannot even see the values)
*(T (*)[N])p (where p is array, T is type of array and N is size of it) [It just does not print accurate]

I want to print it in normal way
Your best bet is to write a print_board routine, which you can then call from GDB.
(which is pretty hard in GDB).
That's because you made it hard.
The problem is that your board, rather than being contiguous in memory (as is customary and would be trivial to print in GDB), is instead spread out in 64 separate chunks of 2 values each.
Since you are using C++, you'll be better off using a vector of vectors:
vector<vector<int>> board;
board.resize(col);
for (int i = 0; i < col; i++) {
board[i].resize(row);
}
(gdb) print board
$1 = std::vector of length 64, capacity 64 =
{std::vector of length 2, capacity 2 = {0, 0},
std::vector of length 2, capacity 2 = {0, 0},
...
P.S. When asking questions, it helps to show actual code. Your question has the wrong type for board, and mixes board with array.
Update:
How can I do that (use print_board from GDB)?
Here is an example. Suppose your source looks like this:
1 #include <stdio.h>
2
3 int main()
4 {
5 int col = 16, row = 2;
6 int **board = new int*[col];
7
8 for (int i = 0; i < col; i++) {
9 board[i] = new int[row];
10 }
11
12 // Initialize elements to something interesting, so we can see them
13 // printed.
14 for (int i = 0; i < col; i++)
15 for (int j = 0; j < row; j++)
16 board[i][j] = 100*i + j;
17
18 return 0;
19 }
20
21 void print_board(int **board, int col, int row)
22 {
23 for (int j = 0; j < row; j++) {
24 for (int i = 0; i < col; i++) {
25 printf("\t%d", board[i][j]);
26 }
27 printf("\n");
28 }
29 }
Then, using GDB:
gdb -q ./a.out
(gdb) break 18
(gdb) run
Breakpoint 2, main () at t.cc:18
18 return 0;
(gdb) call print_board(board, col, row)
0 100 200 300 400 500 600 700 800 900 1000 1100 1200 1300 1400 1500
1 101 201 301 401 501 601 701 801 901 1001 1101 1201 1301 1401 1501
voilĂ 

Related

Kruskal algorithm, cycles and unvisited vertices

Algorithm does not pass through vertex 1(Z) and 4(B). Cycles are for vertices 12-13-14(S-T-K) and 13-15-16(T-L-R), how to fix it?
Below is the command, my code, graph, my output and the input file.
The input file contains the data of one connected graph. Its first line contains an integer Nv that specifies the number of edges of the graph. Then there are Nv lines containing descriptions of the consecutive vertices. The description of each node contains a positive integer corresponding to its identifier and a text string corresponding to its name. It can be assumed that both the number of vertices and the identifiers will not exceed 32,767, the length of the name will not be more than 8 characters, and it will only contain letters or numbers. The next line is the number Ne that specifies the number of edges in the graph. Then there are Ne lines containing the description of the subsequent edges. The description of each edge contains three positive integers, the first two correspond to the identifiers of the vertices connected by the given edge, the third is the weight of this edge.
The output should be exactly as many lines as the edges contain the Minimal Spanning Tree, each line should contain information about one edge. The information for each edge should contain the names of the vertices and the edge weight separated by spaces.
#include <iostream>
#include <algorithm>
#include <vector>
using namespace std;
struct Vertex
{
int id;
char name[8];
};
struct Edges
{
int source;
int destination;
int weight;
};
void quickSort(Edges* tab, int left, int right)
{
if (right <= left)
{
return;
}
int i = left - 1, j = right + 1, pivot = tab[(left + right) / 2].weight;
while (1)
{
while (pivot > tab[++i].weight);
while (pivot < tab[--j].weight);
if (i <= j)
{
swap(tab[i].source, tab[j].source);
swap(tab[i].destination, tab[j].destination);
swap(tab[i].weight, tab[j].weight);
}
else
{
break;
}
}
if (j > left)
{
quickSort(tab, left, j);
}
if (i < right)
{
quickSort(tab, i, right);
}
}
int main()
{
int vertexnumber;
int edgenumber;
Edges* edgeList{};
vector<Edges> MST;
vector<Vertex> vertexList;
cin >> vertexnumber;
for (int i = 0; i < vertexnumber; i++)
{
vertexList.push_back(Vertex());
cin >> vertexList[i].id;
cin >> vertexList[i].name;
}
cin >> edgenumber;
edgeList = new Edges[edgenumber];
for (int i = 0; i < edgenumber; i++)
{
cin >> edgeList[i].source;
cin >> edgeList[i].destination;
cin >> edgeList[i].weight;
}
quickSort(edgeList, 0, edgenumber);
int iterator = 0;
for (int i = 0; i < edgenumber; i++)
{
bool isLoop = false;
int helper = edgeList[i].source;
for (int j = 0; j < MST.size(); j++)
{
for (int k = 0; k < MST.size(); k++)
{
if (MST[k].source == helper)
{
helper = MST[k].destination;
break;
}
if (MST[k].destination == helper)
{
helper = MST[k].source;
break;
}
}
if (edgeList[i].destination == helper)
{
isLoop = true;
break;
}
}
if (!isLoop)
{
MST.push_back(Edges());
MST[iterator].destination = edgeList[i].destination;
MST[iterator].source = edgeList[i].source;
MST[iterator].weight = edgeList[i].weight;
iterator++;
if (MST.size() >= vertexnumber - 1)
{
break;
}
}
}
for (int i = 0; i < MST.size(); i++)
{
for (int j = 0; j < vertexList.size(); j++)
{
if (vertexList[j].id == MST[i].source)
{
cout << vertexList[j].name << " ";
break;
}
}
for (int j = 0; j < vertexList.size(); j++)
{
if (vertexList[j].id == MST[i].destination)
{
cout << vertexList[j].name << " ";
break;
}
}
cout << MST[i].weight << endl;
}
}
S K 60
D O 82
O S 96
F P 108
T K 109
P C 110
W E 115
S T 124
E T 130
G N 135
T R 136
L R 138
F D 139
T L 142
G C 145
16
1 Z
2 G
3 N
4 B
5 F
6 P
7 C
8 W
9 E
10 D
11 O
12 S
13 T
14 K
15 L
16 R
34
1 2 288
1 5 175
1 6 192
2 3 135
2 6 246
2 7 145
3 4 188
3 7 177
3 8 174
4 8 179
4 15 213
5 6 108
5 10 139
6 7 110
6 9 187
6 10 147
6 11 203
7 8 218
7 9 172
8 9 115
8 13 146
8 15 153
9 11 168
9 12 174
9 13 130
10 11 82
11 12 96
12 13 124
12 14 60
13 14 109
13 15 142
13 16 136
14 16 148
15 16 138
There are at least two issues with your code:
When you call your quicksort implementation you should start it with edgenumber - 1 as right border index, otherwise you access uninitialised data.
Your loop detection is not correct because you don't care for the case where there are already three or more edges in MST with the same vertex. Here the path can split but you just follow one of them. Thus you add also cyclic edges to MST and the limit of MST.size() >= vertexnumber - 1 is reached before you could link all vertices to the tree.
I hope this helps. There are plenty of implementations in the net (e.g. see external links in the wikipedia article) where you can study how others have solved the task of loop detection. But if my assumption is right that you are doing this as homework, of course, it is better to try yourself.

Trash in operating memory with dynamic arrays

I've tried to make an algorithm, which counts how many numbers are divided without a remainder. Code works, but every time I run it, I'm getting "trash" numbers in my output. I'm using dynamic arrays to solve a problem.
#include <iostream>
using namespace std;
int main()
{
int N = 30;
int *data = new int [N];
for (int i = 0; i < 100; i++)
{
for (int c = 1; c < N; c++)
{
if (i % c == 0)
{
data[c] += 1;
}
}
}
for (int k = 1; k < N; k++)
{
cout << data[k] << endl;
}
delete [] data;
}
I've expected to have, at least, what C++ Shell says: http://cpp.sh/6xtc
100
50
34
25
20
17
15
13
12
10
10
9
8
8
7
7
6
6
6
5
5
5
5
5
4
4
4
4
4
, but got in different IDE the same result:
100
11932994
34
25
20
17
15
13
12
620757039
37045
11951945
8
11927896
7
7
7290
158
6
5
5
570425383
37040
11951941
4
11927892
4
1835102827
859059803
You do
int *data = new int [N];
And allocate an N-sized array. Then you immediately start trying to increment the values in it:
data[c] += 1;
But what was in there to begin with?
If you want to guarantee that all the values will be initialized to 0, per this answer you can allocate your array with:
int *data = new int [N]();
// ^^^^
<Obligatory "you should just be using std::vector!" comment here.\>
(But actually though, vectors would make this way easier and avoid this issue entirely)
data[c] += 1;
You add something to an uninitialized value. data[c] was not necessarily 0 before that. new does not initialize a dynamic array to zero.
Quit all new/delete and use std::vector<>. And, do learn to use the debugger - really helpful in this case.

How can I fix error when adding elements to my array

I am trying to add elements to my file using a method I have already used and was proven to be successful, however now when I do it I get the numbers I want as well as a bunch of other numbers that aren't in my file and don't make any sense
const int MAX_SIZE = 21;
int readSquare(int square[MAX_SIZE][MAX_SIZE], string inputFileName){ //reads file into an array
int value;
ifstream inFile;
inFile.open(inputFileName);
if (inFile) //if the input file to be read open successfully then goes on
{
int temp;
inFile >> temp;
if (temp>21) {
temp=21;
}
for (int i = 0; i < MAX_SIZE; i++)
{
for(int j = 0; j < MAX_SIZE; j++)
{
inFile >> square[i][j];
}
}
} else {
inFile.close();
return 0; //returns 0 if couldnt open file
}
inFile.close();
cout << "Magic square" << endl;
for(int i=0;i<MAX_SIZE;i++)
{
for(int j=0;j<MAX_SIZE;j++)
{
cout << square[i][j] << " ";
}
cout<<endl;
}
return 1;
}
This is the file I am using on my code
3
4 9 2
3 5 7
8 1 6
And this is the result I get(goes on for a while but I only took the top portion)
4 9 2 3 5 7 8 1 6 16840768 6619136 6643024 23198772 0 1942212500 127 917504 6643024 786434 6643032 0
65536 30 0 31 0 13930549 30 593 6619744 6619744 -2 127 46 6420808 1997546816 -1759127226 -2 6420704 1997359545 4096 4104
0 6420680 6634144 6619136 6421232 4104 6619744 0 3 0 4096 6420732 1997535944 6420804 655612 655360 2 9 0 2 6420976
0 1997378284 6420976 663276 1952 229640288 663200 655360 0 1997377793 6421060 661336 9 16777596 0 13080 236 661336 2 16777596 -530786634
Hat tip to #melpomene for working through the details in the main comments.
Op, you're iterating over the entire range of the array regardless of the availability of input data. I suggest you do the following so the results are less random in appearance:
initialize the values in the 2D array to zero.
limit the input samples to the quantity you're expecting, and not to exceed the size of the array in either dimension.
In your post, you're showing the value of 3 in the first line of the input file. What does that mean -- 3 lines, 3 samples, or 3 samples for each of the 3 lines?
Since the input file has 3 samples per line, I'm guessing the initial value in the data file represents the samples per line where the values for each line are assigned to an individual inner array.
Without deviating too much from your post, consider the following:
// clear the array for easier diags
for (int n = 0; n < MAX_SIZE; n++)
for (int m = 0; m < MAX_SIZE; m++)
square[n][m] = 0;
int cols;
inFile >> cols; // first line of data file indicating the samples in each row
if (cols > MAX_SIZE) // don't exceed the size of the inner array
cols = MAX_SIZE;
for (int i = 0; i < MAX_SIZE; i++)
{
for(int j = 0; j < cols; j++)
{
if (!(inFile >> square[i][j])) // read until EOF
{
i = MAX_SIZE; // force outer loop to terminate since break only affects the inner loop.
break;
}
}
}
See How does ifstream's eof() work?

Array of Pointers getting garbage value in c++

I'm trying to create an array of pointers to a 2D (5 X 12) array in C++.
The ptr array has 5 elements. Each element should hold the address of the 1st element of the respective row of the 2D array. So 1st element should point to 1st element of 1st row, 2nd element should point to 1st element of 2nd row, and so on.
The 5th element of my array of pointers seems to point to a garbage value.
Code and output shown below. Can anyone please let me know why?
#include <iostream>
#include <cstdlib>
#include <iomanip>
using namespace std;
int main( )
{
int rainMatrix[5][12] = {{0}}; //declare and initialize rain matrix
int *matrix_ptr[5] = {NULL};//declare and initialize array of pointers
int **matrix_ptr_ptr = matrix_ptr;
for (int i = 0; i < 5; ++i)
matrix_ptr[i] = &rainMatrix[i][0];
rainGen(matrix_ptr_ptr, 5, 12); //generate a random matrix
//display the matrix
for (int i = 0; i < 5; ++i) {
for (int j = 0; j < 12; ++j) {
cout << setw(2) << rainMatrix[i][j] << " ";
}
cout << endl;
}
for (int i = 0; i < 5; ++i)
cout << setw(2) << *matrix_ptr[i] << " " << rainMatrix[i][0] << endl;
return 0;
}
void rainGen (int **pptr, int row, int col)
{
unsigned int seed = 43;
unsigned int rv;
srand(seed);
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
rv = rand() % 100;
**pptr = rv;
*pptr += 1;
}
pptr++;
}
}
OUTPUT
11 1
88 11
28 88
25 28
1477892712 25
You're manipulating the wrong pointer in the innermost loop. Consider the pointer arithmetic carefully:
pptr essentially points to matrix_ptr[0];
on the first iteration, the double indirection means **pptr will set what you want, but then
*pptr += 1 will modify the contents of matrix_ptr[0], which means it no longer points to the beginning of the matrix.
Subsequent passes through the loop compound the situation drastically.
Modifying pptr won't help because it actually points to the wrong thing: it points to matrix_ptr, so incrementing it merely once moves its address from that of matrix_ptr[0], which points to rainMatrix[0][0], to that of matrix_ptr[1], which points to rainMatrix[1][0]. That is the wrong address for the next entry of the matrix, which is rainMatrix[0][1]. In essence, you've moved to the next row, instead of to the next column.
Try this for the innermost loop instead:
for (int i = 0; i < row; ++i)
{
auto qptr = *pptr;
for (int j = 0; j < col; ++j)
{
rv = rand() % 100;
*qptr = rv;
qptr += 1;
}
pptr++;
}
}
In this case, qptr is given the address of the first entry in the matrix. *qptr = rv sets the value. qptr += 1 increments the position of qptr while leaving *pptr alone - and, by extension, it leaves matrix_ptr[0] alone.
John Perry correctly identified the problem, but you have several option to deal with it. You are incorrectly incrementing *pptr += 1 Beyond using auto, you can simply index the pointer with the offset of j, e.g.
*(*pptr + j) = rv;
or
(*pptr)[j] = rv;
Either will work. Putting it together in your rainGen function, you could do:
void rainGen (int **pptr, int row, int col)
{
unsigned int seed = 43;
unsigned int rv;
srand(seed);
for (int i = 0; i < row; ++i) {
for (int j = 0; j < col; ++j) {
rv = rand() % 100;
// *(*pptr + j) = rv; /* or */
(*pptr)[j] = rv;
}
pptr++;
}
}
(note: seed and srand(seed) should be moved to main() if there is the potential that rainGen could be called more than once -- srand should only be called once)
Example Use/Output
Both will produce the desired output:
$ ./bin/raingen
72 71 65 94 0 13 49 17 36 49 67 51
87 68 45 15 91 72 16 80 77 35 9 81
11 88 73 59 24 22 37 48 45 54 94 45
19 44 62 56 45 81 59 32 49 4 99 92
28 16 24 5 3 34 38 14 22 12 26 98
72 72
87 87
11 11
19 19
28 28
You are modifying the pointers in the pointer-array matrix_ptr within your rainGen function, so that all of them point past the end and further accesses go to "random" memory locations, which is undefined behavior. Tools like valgrind can find such errors.

concatenating arrays, array 1 memory gone C++

Program consists of array1[20] and array2[40] from input files. Array1 is then added on to the end of array2 (after which they will be sorted chronologically, but I havent gotten there yet bc I am stuck on this). The final result will be printed; I did not include this portion of the code nor the code for inputing files to make it easier for you to read :) thanks for the help.
The code yeilds no errors. The input is number 1 through 20 on both input files and the output reads
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 135062784 135305664 134511120 135308884 6 0 6 16 135303844 134511520 134511136 134957510 135308884 135111932 135120188 0 134511156 135303952 134511168 134805750
int readSortedArray (int array[20], int count, istream& infile)
{
count = 0;
while( (count < 20) && (infile >> array[count]) )
{
count++;
}
return count;
}
int main ()
{
int array[20], array1[20], array2[40];
int count, count1, count2, x;
count1 = readSortedArray(array1, count1, infile1);
count2 = readSortedArray(array2, count2, infile2);
for (int i=1; i < count1 + 1; i++ )
{
array1[i - 1] >> array2[count2 + i];
}
return 0;
}
Seems the for loop in the main function should be this (i should start at 0). And make sure infile2 really contains what you think it contains.
for (int i=0; i < count1; i++ )
{
array2[count2 + i] = array1[i];
}