Segmentation Fault SIGSEGV while running C++ code - c++

I am getting error while executing my C++ code
Error is:
The inferior stopped because it received a signal from the operating system.
Signal name: SIGSEGV
Signal meaning : Segmentation fault
IDE : QT Creator
I know there is something wrong with the way I have declared the 2 dimentional array of structs in header file
But don't know exactly what!
Can someone please explain..
Please note, I plan to create multiple instances of Datamatrix class as part of my work in a recursive or iterative manner.
Each instance containing 2 dimensional array of structs..
So Any help explanation is welcome.
There are many areas of C++ which I have not explored! still learning :)
Please see the code below
main.cpp
----------
#include <iostream>
#include "datamatrix.h"
#include "utils.h"
using namespace std;
void printArray(int items[],int size)
{
for(int j=0;j<size;j++)
{
cout<<items[j]<<" ";
}
cout<<endl;
}
int main()
{
cout << "Hello there" << endl;
int a[250];
for(int i=0;i<250;i++)
{
a[i] = i+1;
}
printArray(a,250);
DataMatrix *matrix = new DataMatrix();
Utils u;
u.myFunction(matrix); **<-- All goes well till here**
cout<<"End of Main method"; **<-- This line of code is never reached**
return 0;
}
datamatrix.h
------------
#ifndef DATAMATRIX_H
#define DATAMATRIX_H
#include <string>
using namespace std;
struct KVPair { **<--- This is the line where issue comes**
string key;
double value;
};
class DataMatrix
{
public:
DataMatrix();
KVPair matrix[250][130];
};
#endif // DATAMATRIX_H
datamatrix.cpp
--------------
#include "datamatrix.h"
DataMatrix::DataMatrix()
{
for(int i=0;i<250;i++)
{
for(int j=0;j<130;j++)
{
string k = "f"+i+1;
matrix[i][j].key = k;
matrix[i][j].value = i+5;
}
}
}
utils.h
--------
#ifndef UTILS_H
#define UTILS_H
#include "datamatrix.h"
class Utils
{
public:
Utils();
DataMatrix myFunction(DataMatrix* dm);
};
#endif // UTILS_H
utils.cpp
---------
#include "utils.h"
#include <algorithm>
#include <time.h>
#include <math.h>
#include "datamatrix.h"
Utils::Utils()
{
}
DataMatrix Utils::myFunction(DataMatrix* dm)
{
printf("inside myFunction ");
}
Just thought to add console output as well(please see console output below)
Hello there
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 5
7 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107
108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167
168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187
188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207
208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
248 249 250
inside myFunction
Thanks in advance

The following line:
string k = "f"+i+1;
Causes the issue. It takes the address far beyond the string literal "f", which is an invalid address, and passes that to std::string constructor, which reads from that address to determine the length of the string and causes the crash.
One way to fix would be:
string k = "f" + std::to_string(i + 1);

Eliminating the one warning from gcc -Wall prevents the crash. One way to do that is to add a return value in Utils::myFunction, as follows.
DataMatrix Utils::myFunction(DataMatrix* dm)
{
printf("inside myFunction ");
return *dm;
}
It appears that main allocates space for a DataMatrix on the stack with the expectation that the call to Utils::myFunction will populate that space. The following gdb session excerpt on a binary with the added return statement in Utils::myFunction reinforces that claim.
(gdb) break main.cpp:30
Breakpoint 1 at 0xfaa: file main.cpp, line 30.
(gdb) run > /dev/null
Starting program: main > /dev/null
Breakpoint 1, main () at main.cpp:30
30 u.myFunction(matrix);
(gdb) print matrix
$1 = (DataMatrix *) 0x7ffff7e95010
(gdb) set $matrix = (DataMatrix *) ($rbp - 0x13d640)
(gdb) print matrix.matrix[249][129].key
$2 = "\030J\017\vw\b\200"
(gdb) print $matrix.matrix[249][129].key
$3 = <incomplete sequence \303>
(gdb) next
31 cout<<"End of Main method";
(gdb) print $matrix.matrix[249][129].key
$4 = "\030J\017\vw\b\200"
(gdb)
In my testing, the crash occurs during an attempt to deallocate an uninitialized KVPair consisting of arbitrary stack contents. The details of that are not revealed in the preceding gdb session excerpt, but the point is that after Utils::myFunction returns a value other than void, the two copies of the DataMatrix agree about the contents of the last array element (the first one processed in the destructor, in my testing). The following excerpt from gdb disassembly explains the $rbp offset used for $matrix.
0x0000555555554fc7 <+183>: lea -0x13d640(%rbp),%rax
0x0000555555554fce <+190>: mov %rax,%rdi
0x0000555555554fd1 <+193>: callq 0x555555555092 <DataMatrix::~DataMatrix()>
Another way to prevent the crash is to declare Utils::myFunction as returning void, in which case main does not allocate space on the stack, and there is no call to the DataMatrix destructor within main.

Related

Question about tabling and declaring functions in main

the problem is in the int main()
#include <iostream>
#include <iomanip>
#include <fstream>
#include <cstring>
using namespace std;
const int R = 15;
const int C = 20;
void clearArray(int arr[R][C])
{
for (int i = 0; i < R; i++)
{
for (int j = 0; j < C; j++)
{
arr[i][j] = 0;
}
}
}
void makeSpiral(int arr[R][C],int r , int c)
{
int i, a = 0, b = 0;
int value = 1;
while (a < r && b < c)
{
for (i = a; i < r; ++i)
{
arr[i][b] = value++;
}
b++;
for (i = b; i < c; ++i)
{
arr[r - 1][i] = value++;
}
r--;
if (a < r)
{
for (i = r - 1; i >= a; --i)
{
arr[i][c-1] = value++;
}
c--;
}
if (b < c)
{
for (i = c - 1; i >= b; --i)
{
arr[a][i] = value++;
}
a++;
}
}
}
void printSpiral(int arr[R][C],int r , int c, char str[])
{
str[30];
ofstream fout;
fout.open(str, ios::out | ios::app);
if (!fout)
{
cout << "Error: file could not be opened" << endl;
exit(1);
}
fout << endl;
fout << "---------------------------------------------";
for (int i = 0; i < r; i++)
{
fout << endl;
for (int j = 0; j < c; j++)
{
fout <<setw(5)<< arr[i][j] << " ";
}
}
fout.close();
}
int main(int argc, char *argv[])
{
char str[30];
ofstream fout;
int r,c;
int i,j,t;
int arr[R][C];
if (argc < 2)
{
cout << "Error missing file name!" << endl;
return -1;
}
strcpy(str, argv[1]);
int matrix [R][C] = {{1,1},{2,2},{3,3},{4,4},{5,5},{4,7},{7,4},{15,20}};
for (i = 0 ; i < 8 ; i++)
{
clearArray(matrix);
makeSpiral(matrix,R,C);
printSpiral (matrix,R,C,str);
}
return 0;
}
I'm a new C++ programmer please go easy on me. So i have this piece of code, the professor requires me to store corner sizes of a spiral matrix into a table, then use a loop to call out my functions so i don't have to call my functions repeatedly like this:
clearArray(matrix);
makeSpiral(matrix,1,1);
printSpiral (matrix,1,1,str);
clearArray(matrix);
makeSpiral(matrix,2,2);
printSpiral (matrix,2,2,str);
clearArray(matrix);
makeSpiral(matrix,3,3);
printSpiral (matrix,3,3,str);
clearArray(matrix);
makeSpiral(matrix,4,4);
printSpiral (matrix,4,4,str);
I want to print a counter-clockwise matrix 8 times which with corner 1 by 1 ; 2 by 2; 3 by 3; 4 by 4; 5 by 5; 4 by 7; 7 by 4; and 15 by 20.
My code doesn't give me the correct output, can you tell me where I did wrong, thank you!
The output that i supposed to have
---------------------------------
1
---------------------------------
1 3
---------------------------------
3
2
---------------------------------
1 4
2 3
---------------------------------
1 8 7
2 9 6
3 4 5
---------------------------------
1 12 11 10
2 13 16 9
3 14 15 8
4 5 6 7
---------------------------------
1 16 15 14 13
2 17 24 23 12
3 18 25 22 11
4 19 20 21 10
5 6 7 8 9
---------------------------------
1 18 17 16 15 14 13
2 19 28 27 26 25 12
3 20 21 22 23 24 11
4 5 6 7 8 9 10
---------------------------------
1 18 17 16
2 19 28 15
3 20 27 14
4 21 26 13
5 22 25 12
6 23 24 11
7 8 9 10
---------------------------------
1 20 19 18 17 16 15 14
2 21 32 31 30 29 28 13
3 22 23 24 25 26 27 12
4 5 6 7 8 9 10 11
---------------------------------
1 16 15 14
2 17 24 13
3 18 23 12
4 19 22 11
5 20 21 10
6 7 8 9
What my code output looks like:
---------------------------------------------------------
1 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
2 67 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 47
3 68 125 174 173 172 171 170 169 168 167 166 165 164 163 162 161 160 107 46
4 69 126 175 216 215 214 213 212 211 210 209 208 207 206 205 204 159 106 45
5 70 127 176 217 250 249 248 247 246 245 244 243 242 241 240 203 158 105 44
6 71 128 177 218 251 276 275 274 273 272 271 270 269 268 239 202 157 104 43
7 72 129 178 219 252 277 294 293 292 291 290 289 288 267 238 201 156 103 42
8 73 130 179 220 253 278 295 296 297 298 299 300 287 266 237 200 155 102 41
9 74 131 180 221 254 279 280 281 282 283 284 285 286 265 236 199 154 101 40
10 75 132 181 222 255 256 257 258 259 260 261 262 263 264 235 198 153 100 39
11 76 133 182 223 224 225 226 227 228 229 230 231 232 233 234 197 152 99 38
12 77 134 183 184 185 186 187 188 189 190 191 192 193 194 195 196 151 98 37
13 78 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 97 36
14 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 35
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
------------------------------------------------------------
1 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
2 67 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 47
3 68 125 174 173 172 171 170 169 168 167 166 165 164 163 162 161 160 107 46
4 69 126 175 216 215 214 213 212 211 210 209 208 207 206 205 204 159 106 45
5 70 127 176 217 250 249 248 247 246 245 244 243 242 241 240 203 158 105 44
6 71 128 177 218 251 276 275 274 273 272 271 270 269 268 239 202 157 104 43
7 72 129 178 219 252 277 294 293 292 291 290 289 288 267 238 201 156 103 42
8 73 130 179 220 253 278 295 296 297 298 299 300 287 266 237 200 155 102 41
9 74 131 180 221 254 279 280 281 282 283 284 285 286 265 236 199 154 101 40
10 75 132 181 222 255 256 257 258 259 260 261 262 263 264 235 198 153 100 39
11 76 133 182 223 224 225 226 227 228 229 230 231 232 233 234 197 152 99 38
12 77 134 183 184 185 186 187 188 189 190 191 192 193 194 195 196 151 98 37
13 78 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 97 36
14 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 35
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
---------------------------------------------------------
1 66 65 64 63 62 61 60 59 58 57 56 55 54 53 52 51 50 49 48
2 67 124 123 122 121 120 119 118 117 116 115 114 113 112 111 110 109 108 47
3 68 125 174 173 172 171 170 169 168 167 166 165 164 163 162 161 160 107 46
4 69 126 175 216 215 214 213 212 211 210 209 208 207 206 205 204 159 106 45
5 70 127 176 217 250 249 248 247 246 245 244 243 242 241 240 203 158 105 44
6 71 128 177 218 251 276 275 274 273 272 271 270 269 268 239 202 157 104 43
7 72 129 178 219 252 277 294 293 292 291 290 289 288 267 238 201 156 103 42
8 73 130 179 220 253 278 295 296 297 298 299 300 287 266 237 200 155 102 41
9 74 131 180 221 254 279 280 281 282 283 284 285 286 265 236 199 154 101 40
10 75 132 181 222 255 256 257 258 259 260 261 262 263 264 235 198 153 100 39
11 76 133 182 223 224 225 226 227 228 229 230 231 232 233 234 197 152 99 38
12 77 134 183 184 185 186 187 188 189 190 191 192 193 194 195 196 151 98 37
13 78 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 97 36
14 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 35
15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
--------------------------------------------------------
......
It prints the 15x20 corner size 8 times.
In your main function, arguments to makeSpiral are fixed R and C. This means makeSpiral always tries to fill a 15 rows, 20 columns spiral matrix to your matrix:
makeSpiral(matrix,R,C);
printSpiral(matrix,R,C,str);
You may want this instead:
int matrix[R][C]; // no need of initialization
int matrixSize[8][2] = {{1,1},{2,2},{3,3},{4,4},{5,5},{4,7},{7,4},{15,20}};
for (i = 0 ; i < 8 ; i++) {
clearArray(matrix, matrixSize[i][0], matrixSize[i][1]);
makeSpiral(matrix, matrixSize[i][0], matrixSize[i][1]);
printSpiral (matrix, matrixSize[i][0], matrixSize[i][1], str);
}
Here you use an assist matrixSize to store expected matrix sizes. Within the for loop makeSpiral will fill matrixSize[i][0] rows, matrixSize[i][1] columns only, so does printSpiral.

Arduino insertion sort issue with struct array

Here is the struct:
struct RGB {
byte r;
byte g;
byte b;
byte v;
};
And here is the sorting function:
void insertion_sort(RGB arr[], size_t capacity) {
RGB temp;
size_t j;
for(size_t i = 1; i < capacity; i++) {
temp = arr[i];
j = i - 1;
while(j >= 0 && arr[j].v > temp.v) {
arr[j+1] = arr[j];
j--;
}
arr[j+1] = temp;
}
}
the v member of the RGB struct is the object's position in the array before scrambling (and hopefully where it ends up after sorting). Here is the output when printing the v member of every element of the array:
165 171 53 164 171 13 13 167 156 168 163 14 15 16 17 18 19 20 20 156 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 142 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149
I get the same output every time.
There are 150 elements in the array, and everything seems fine after 21. The issue is that the elements before that are wrong, and also made up of values higher than 149. Currently, the b and g members of RGB are all 0 throughout the array, and r is evenly-spaced values from 0-254.
It should be noted that the exact same sorting function works when I recreated everything in C++, and it even works to sort an array of ints in Arduino. The only issue is sorting an array of RGB structs, which seems to be causing memory issues.
Your problem is the definition of j.
Your options are:
Serial output in critical lines and analyze the serial monitor -> Arduinos way of debuging
using one of the hundred tested sorting functions (e.g. here on stack exchange) like quick sort etc.
using the std::sort
For the last option you have to:
The best solution is to use the C++ standard library function std::sort. This function is type-safe, and doesn't require you to cast anything to void * and back, and you don't have to manually enter the sizes of the array and its elements.
#include < Arduino_Helpers.h\>
#include < AH/STL/algorithm\>
#include < AH/STL/iterator\>
auto cmpfunc = [](RGB A, RGB B) { return A.value < B.value; };
// or if you do not like this notation use
bool cmpfunc(RGB A, RGB B) {
return A.value < B.value;
}
std::sort(std::begin(RGB arr[]), std::end(RGB arr[]), cmpfunc); // Dummy for a RGB arr[] containing all your values
-
The problem was because of the size_t datatype, which is unsigned and could not become a value < 0 when it was supposed to. Thank you #JohnFilleau

Why are my bit shifts giving incorrect numbers

I'm trying to store a number in an array of 4 integers. The array is in the class Num. My problem is that when I call getValue, the function returns numbers that aren't correct. I tried go through the program on paper, doing all the calculations in Microsoft's calculator, and the program should give the correct output. I don't even know which function could be problematic since there aren't any errors or warnings, and both worked on paper.
21 in binary:10101
What I'm trying to do:
Input to setValue function: 21
setValue puts the first four bits of 21 (0101) into num[3]. So num[3] is now 0101 in binary. Then it should put the next four bits of 21 into num[2]. The next four bits are 0001 so 0001 goes into num[2] The rest of the bits are 0 so we ignore them. Now num is {0,0,1,5}. getValue first goes to num[3]. There is 5 which is 0101 in binary. So it puts that into the first four bits of return value. It then puts 0001 into the next four bits. The rest of the numbers are 0 so it is supposed to ignore them. Then the output of the function getValue is directly printed out. The actual output is at the bottom.
My code:
#include <iostream>
class Num {
char len = 4;
int num[4];
public:
void setValue(int);
int getValue();
};
void Num::setValue(int toSet)
{
char len1=len-1;
for (int counter = len1;counter>=0;counter--)
{
if(toSet&(0xF<<(len1-counter))!=0)
{
num[counter]=(toSet&(0xF<<(len1-counter)))>>len1-counter;
} else {
break;
}
}
}
int Num::getValue()
{
char len1 = len-1;
int returnValue = 0;
for(char counter = len1; counter>=0;counter--)
{
if (num[counter]!=0) {
returnValue+=(num[counter]<<(len1-counter));
} else {
break;
}
}
return returnValue;
}
int main()
{
int x=260;
Num number;
while (x>0)
{
number.setValue(x);
std::cout<<x<<"Test: "<<number.getValue()<<std::endl;
x--;
}
std::cin>>x;
return 0;
}
Output:
260Test: -1748023676
259Test: 5
258Test: 5
257Test: 1
256Test: 1
255Test: 225
254Test: 225
253Test: 221
252Test: 221
251Test: 213
250Test: 213
249Test: 209
248Test: 209
247Test: 193
246Test: 193
245Test: 189
244Test: 189
243Test: 181
242Test: 181
241Test: 177
240Test: 177
239Test: 177
238Test: 177
237Test: 173
236Test: 173
235Test: 165
234Test: 165
233Test: 161
232Test: 161
231Test: 145
230Test: 145
229Test: 141
228Test: 141
227Test: 133
226Test: 133
225Test: 1
224Test: 1
223Test: 161
222Test: 161
221Test: 157
220Test: 157
219Test: 149
218Test: 149
217Test: 145
216Test: 145
215Test: 129
214Test: 129
213Test: 125
212Test: 125
211Test: 117
210Test: 117
209Test: 113
208Test: 113
207Test: 113
206Test: 113
205Test: 109
204Test: 109
203Test: 101
202Test: 101
201Test: 97
200Test: 97
199Test: 81
198Test: 81
197Test: 77
196Test: 77
195Test: 5
194Test: 5
193Test: 1
192Test: 1
191Test: 161
190Test: 161
189Test: 157
188Test: 157
187Test: 149
186Test: 149
185Test: 145
184Test: 145
183Test: 129
182Test: 129
181Test: 125
180Test: 125
179Test: 117
178Test: 117
177Test: 113
176Test: 113
175Test: 113
174Test: 113
173Test: 109
172Test: 109
171Test: 101
170Test: 101
169Test: 97
168Test: 97
167Test: 81
166Test: 81
165Test: 77
164Test: 77
163Test: 69
162Test: 69
161Test: 1
160Test: 1
159Test: 97
158Test: 97
157Test: 93
156Test: 93
155Test: 85
154Test: 85
153Test: 81
152Test: 81
151Test: 65
150Test: 65
149Test: 61
148Test: 61
147Test: 53
146Test: 53
145Test: 49
144Test: 49
143Test: 49
142Test: 49
141Test: 45
140Test: 45
139Test: 37
138Test: 37
137Test: 33
136Test: 33
135Test: 17
134Test: 17
133Test: 13
132Test: 13
131Test: 5
130Test: 5
129Test: 1
128Test: 1
127Test: 225
126Test: 225
125Test: 221
124Test: 221
123Test: 213
122Test: 213
121Test: 209
120Test: 209
119Test: 193
118Test: 193
117Test: 189
116Test: 189
115Test: 181
114Test: 181
113Test: 177
112Test: 177
111Test: 177
110Test: 177
109Test: 173
108Test: 173
107Test: 165
106Test: 165
105Test: 161
104Test: 161
103Test: 145
102Test: 145
101Test: 141
100Test: 141
99Test: 133
98Test: 133
97Test: 1
96Test: 1
95Test: 161
94Test: 161
93Test: 157
92Test: 157
91Test: 149
90Test: 149
89Test: 145
88Test: 145
87Test: 129
86Test: 129
85Test: 125
84Test: 125
83Test: 117
82Test: 117
81Test: 113
80Test: 113
79Test: 113
78Test: 113
77Test: 109
76Test: 109
75Test: 101
74Test: 101
73Test: 97
72Test: 97
71Test: 81
70Test: 81
69Test: 77
68Test: 77
67Test: 5
66Test: 5
65Test: 1
64Test: 1
63Test: 161
62Test: 161
61Test: 157
60Test: 157
59Test: 149
58Test: 149
57Test: 145
56Test: 145
55Test: 129
54Test: 129
53Test: 125
52Test: 125
51Test: 117
50Test: 117
49Test: 113
48Test: 113
47Test: 113
46Test: 113
45Test: 109
44Test: 109
43Test: 101
42Test: 101
41Test: 97
40Test: 97
39Test: 81
38Test: 81
37Test: 77
36Test: 77
35Test: 69
34Test: 69
33Test: 1
32Test: 1
31Test: 97
30Test: 97
29Test: 93
28Test: 93
27Test: 85
26Test: 85
25Test: 81
24Test: 81
23Test: 65
22Test: 65
21Test: 61
20Test: 61
19Test: 53
18Test: 53
17Test: 49
16Test: 49
15Test: 49
14Test: 49
13Test: 45
12Test: 45
11Test: 37
10Test: 37
9Test: 33
8Test: 33
7Test: 17
6Test: 17
5Test: 13
4Test: 13
3Test: 5
2Test: 5
1Test: 1
I compiled this with g++ 6.3.0 with the command g++ a.cpp -o a.exe
When compiling with -Wall, there are a number of warnings:
orig.cpp: In member function ‘void Num::setValue(int)’:
orig.cpp:15:39: warning: suggest parentheses around comparison in operand of ‘&’ [-Wparentheses]
if(toSet&(0xF<<(len1-counter))!=0)
~~~~~~~~~~~~~~~~~~~~~^~~
orig.cpp:17:61: warning: suggest parentheses around ‘-’ inside ‘>>’ [-Wparentheses]
num[counter]=(toSet&(0xF<<(len1-counter)))>>len1-counter;
~~~~^~~~~~~~
orig.cpp: In member function ‘int Num::getValue()’:
orig.cpp:30:24: warning: array subscript has type ‘char’ [-Wchar-subscripts]
if (num[counter]!=0) {
^
orig.cpp:31:38: warning: array subscript has type ‘char’ [-Wchar-subscripts]
returnValue+=(num[counter]<<(len1-counter));
^
If you were to print the values of num before changing them, you'd see that some might be non-zero (i.e. they are uninitialized), which causes undefined behavior and probably breaks your for loops in getValue and setValue.
So change:
int num[4];
Into:
int num[4] = { 0 };
Here's a cleaned up version with the warnings fixed:
#include <iostream>
class Num {
int len = 4;
int num[4] = { 0 };
public:
void setValue(int);
int getValue();
void showval();
};
void Num::setValue(int toSet)
{
int len1=len-1;
for (int counter = len1;counter>=0;counter--)
{
if ((toSet & (0xF << (len1-counter))) != 0)
{
num[counter] = (toSet & (0xF << (len1-counter))) >> (len1-counter);
} else {
break;
}
}
}
int Num::getValue()
{
int len1 = len-1;
int returnValue = 0;
for(int counter = len1; counter>=0;counter--)
{
if (num[counter]!=0) {
returnValue+=(num[counter]<<(len1-counter));
} else {
break;
}
}
return returnValue;
}
void Num::showval()
{
for (int i = 0; i < len; ++i)
std::cout << i << ": show: " << num[i] << "\n";
#if 0
for (int i = 0; i < len; ++i)
num[i] = 0;
#endif
}
int main()
{
int x=260;
Num number;
number.showval();
while (x>0)
{
number.setValue(x);
std::cout << x << " Test: " << number.getValue() << std::endl;
x--;
}
std::cin>>x;
return 0;
}
To break a number into nibbles, the shift counts should be multiples of 4. Otherwise slices of 4 bits are extracted that don't line up.
00010101 (21)
^^^^ first nibble
^^^^ second nibble
The second nibble is displaced by 4 bits so it needs to be shifted right by 4, not by 1.
You could multiply your shift counts by 4, but there is an easier way: only ever shift by 4. For example:
for (int i = len - 1; i >= 0; i--) {
num[i] = toSet & 0xF;
toSet >>= 4;
}
Then every iteration extracts the lowest nibble in toSet, and shifts toSet over so that the next nibble becomes the lowest nibble.
I didn't put in a break and there should not be one. It definitely shouldn't be the kind of break that you had, which stops the loop also whenever a number has a zero in the middle of it (for example in 0x101 the middle 0 causes the loop to stop). The loop also should not stop when the entire rest of the number is zero, since that leaves junk in the other entries of num.
It's more common to store the lowest nibble in the 0th element and so on (then you don't have to deal with all the "reverse logic" with down-counting loops and subtracting things from the length) but that's up to you.
Extracting the value can be done symmetrically, building up the result while shifting it, instead of shifting every piece into its final place immediately. Or just multiply (len1-counter) by 4. While extracting the value, you also cannot stop when num[i] is zero, since that does not prove that the rest of the number is zero too.

How to scan input from user if graph is given in form of adjancency list?

I have an input in format as shown in below Image.I am using the vector graph[200] to read input. Let's suppose program read first number of first row and column (as shown in Image) . Now I want to add all vertices which is connected to first node like graph[1].push_back(next integer in same row) and so on . But when should I stop reading input for particular Node(graph[i]). Because after reading first row I need to add vertices into another graph[i+1] to node's corresponding list . If you don't understand my questions plz have a look to my code.
#include <bits/stdc++.h>
using namespace std;
vector<int> graph[201];
int main()
{
int n=2,i,node,temp;
for(i=1;i<=n;i++)
{
cin>>node;
while(scanf("%d",&temp)!=EOF/*What is the correct conditon to stop loop*/)
{
graph[node].push_back(temp);
}
}
return 0;
}
Input format :
1 37 79 164 155 32 87 39 113 15 18 78 175 140 200 4 160 97 191 100 91 20 69 198 196
20 123 134 10 141 13 12 43 47 3 177 101 179 77 182 117 116 36 103 51 154 162 128 30
3 48 123 134 109 41 17 159 49 136 16 130 141 29 176 2 190 66 153 157 70 114 65 173 104 194 54
14 91 171 118 125 158 76 107 18 73 140 42 193 127 100 84 121 60 81 99 80 150 55 1 35 23 93
5 193 156 102 118 175 39 124 119 19 99 160 75 20 112 37 23 145 135 146 73 35
60 155 56 52 120 131 160 124 119 14 196 144 25 75 76 166 35 87 26 20
7 156 185 178 79 27 52 144 107 78 22 71 26 31 15 56 76 112 39 8 113 93
8 185 155 171 178 108 64 164 53 140 25 100 133 9 52 191 46 20 150 144 39 62 131 42 119 127 31 7
9 91 155 8 160 107 132 195 26 20 133 39 76 100 78 122 127 38 156 191 196
10 190 184 154 49 2 182 173 170 161 47 189 101 153 50 30 109 177 148 179 16 163 116 13 90 185
111 123 134 163 41 12 28 130 13 101 83 77 109 114 21 82 88 74 24 94 48 33
12 161 109 169 21 24 36 65 50 2 101 159 148 54 192 88 47 11 142 43 70 182 177 179 189 194 33
13 161 141 157 44 83 90 181 41 2 176 10 29 116 134 182 170 165 173 190 159 47 82 111 142 72 154 110 21 103 130 11 33 138 152
and so on...
Here is the screenshot of my input format
Assuming you want to read line-by-line basis, you could do following:
#include <bits/stdc++.h>
using namespace std;
vector<int> graph[201];
int main(){
string line;
int n=2,i,node,temp;
for(i=1;i<=n;i++){
getline(cin, line);
istringstream in( line );
in>>node;
while(in>>temp){
graph[node].push_back(temp);
}
}
return 0;
}

Getline puts program on pause

When "text" is larger than about 280 numbers the program waits ...
With any "text" of 280 numbers, it works fine.
#include <iostream>
#include <string>
using namespace std;
int main()
{
string text;
getline (cin, text);
cout << text;
}
eg:
167 214 280 265 278 292 196 249 242 297 7 125 151 4 25 172 293 157 290 277 240 155 201 90 44 230 94 185 184 65 189 159 74 30 59 279 169 136 142 80 46 124 66 203 138 182 171 241 267 294 32 233 165 39 149 181 156 170 137 96 130 238 239 37 298 48 288 6 100 174 268 144 272 109 275 190 160 154 57 15 83 16 183 236 95 97 147 215 77 34 219 91 68 81 52 207 187 105 229 153 243 20 71 53 3 102 259 13 115 123 98 193 87 208 120 221 113 261 126 178 111 133 255 36 287 93 228 263 47 227 188 191 295 205 28 82 244 152 281 166 58 192 162 60 256 76 50 179 235 247 282 118 88 212 112 21 273 141 222 56 209 134 237 2 121 104 23 150 194 146 24 300 64 92 78 79 116 108 286 223 70 61 67 284 19 33 173 216 42 164 29 199 63 69 140 132 211 101 103 119 106 198 296 168 224 158 232 27 254 246 262 110 250 225 135 86 26 51 180 231 114 257 75 202 217 251 218 18 89 213 85 220 117 266 206 127 234 197 291 248 14 258 129 226 148 260 84 204 73 299 31 264 276 107 11 145 1 54 200 49 72 177 62 45 163 271 274 270 195 186 252 139 99 55 41 38 253 285 5 176 283 22 122 161 17 175 131 43 289 269 9 40 245 12 10 143 35 210 128 8
The only reason I could imagine your code is pausing is if you were overfilling the space allocated for a string. This seems extremely unlikely. There is a limit to the maximum size for a string based on the size of size_t but typically 32 bits are allocated for size_t... This means that the max number of characters for a string is typically 2^32 - 1 characters. Obviously, you are nowhere near reaching that length.
In normal circumstances, you are far more likely to be bound by the amount of space that your system can allocate for the string. This is dependent on the amount of memory available and how your system breaks it up.
Both of these situations seem extremely unlikely.
In this situation, the issue is most likely an issue with your compiler or platform...
What's your reason for taking in such a long string? Have you considered other approaches like reading in the integers from a text file? You could use a vector to store the integers in a more organized way by reading them in individually from the text file, just a thought.