Printing a hex array in console - c++

I have a uint8_t type array, 4x4 dimensions, I have use nested for loops to display the array, hex values are converted to hex string through sprintf().
void hexD(uint8_t state[4][4])
{
char x[2];
for(int i = 0; i < 4; i++)
{
cout << "\n";
for(int j = 0; j < 4; j++)
{
cout << j <<"\n"; //displays the value of j
sprintf(x, "%x", state[i][j]);
cout << x << "\t";
}
}
}
The problem is inner for loop which runs endlessly as value of j starts from 0 then 1 then 2 but instead of going to 3 it gets back to 1, j swaps between 1 and 2 thus the loop in running infinitely.
Any solutions to this.
Thanks.

Depending on your values in state[4][4], you're likely to end up
overflowing the x array (remember, you need a place for at most FF (2 chars) + 1 for the terminating '\0').
That's undefined behavior.
Fix it (char x[3];) and you should be fine. Here's an mcve:
#include <iostream>
#include <cstdint>
#include <cstdio>
using namespace std;
void hexD(uint8_t state[4][4])
{
char x[3];
for(int i = 0; i < 4; i++)
{
cout << "\n";
for(int j = 0; j < 4; j++)
{
cout << j <<"\n"; //displays the value of j
sprintf(x, "%x", state[i][j]);
cout << x << "\t";
}
}
}
uint8_t state[4][4]={
255,255,255,255,
0, 1, 2, 3,
0, 1, 2, 3,
0, 1, 2, 3,
};
int main()
{
hexD(state);
}

char x[2];
You only have two bytes for your "hex output" but no available space for a null character.
Writing more to an array with lesser capacity is undefined behavior.
Increase x array size to 3:
char x[3];
since as per sprintf:
A terminating null character is automatically appended after the
content.
Thus, you have a total of three characters including the null character.

Your x has only two spaces, but you are writing more characters into it. For example, a 0 in hex is "00", two characters plus a closing '\0'.
That overwrites neighboring memory, and your j happens to be there and get overwritten.
Increase the size of x[], and it should work.

Related

Function to delete an element from an array not working

I wanted to write a function which upon being called deletes an element from an array given that the parameters passed in the deleteArray function were the array, its length and the value of the element to be deleted.
Tried breaking out of the for loop while transversing through the array if the element was found and then tried using i's value in another for loop to replace the current elements with their next element.
like array[j] = array[j + 1]
Here is the code:
#include <iostream>
using namespace std;
void deleteElement(int[], int, int);
int main() {
int array1[] = { 1, 4, 3, 5, 6 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, length, 4);
cout << "\nIn main function\n";
for (int i = 0; i < length; i++) {
cout << array1[i];
}
return 0;
}
void deleteElement(int array2[], int length, int element) {
int i = 0;
for (int i; i < length; i++) {
if (array2[i] == element) {
for (int j = i; j < length; j++) {
array2[j] = array2[j + 1];
}
break;
}
}
if (i == (length - 1)) {
cout << ("Element doesn't exist\n");
}
cout << "Testing OP in deleteElement\n";
for (int i = 0; i < length; i++) {
cout << array2[i];
}
}
Expected:
Testing OP in deleteElement
14356
In main function
1356
Actual:
Testing OP in deleteElement
14356
In main function
14356
The problem is rather silly:
At the beginning of deleteElement(), you define i with int i = 0;, but you redefine another variable i as a local index in each for loop. The for loop introduces a new scope, so the int i definition in the first clause of the for loop defines a new i, that shadows the variable with the same name defined in an outer scope.
for (int i; i < length; i++) {
And you do not initialize this new i variable.
There are 2 consequences:
undefined behavior in the first loop as i is uninitialized. The comparison i < length might fail right away.
the test if (i == (length - 1)) { tests the outer i variable, not the one that for iterated on. Furthermore, the test should be if (i == length) {
There are other issues:
the nested for loop iterates once too many times: when j == length - 1, accessing array[j + 1] has undefined behavior.
you do not update length, so the last element of the array is duplicated. You must pass length by reference so it is updated in the caller's scope.
Here is a corrected version:
#include <iostream>
using namespace std;
void deleteElement(int array2[], int& length, int element);
int main() {
int array1[] = { 1, 4, 3, 5, 6 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, &length, 4);
cout << "\nIn main function\n";
for (int i = 0; i < length; i++) {
cout << array1[i] << " ";
}
return 0;
}
void deleteElement(int array2[], int& length, int element) {
int i;
for (i = 0; i < length; i++) {
if (array2[i] == element)
break;
}
if (i == length) {
cout << "Element doesn't exist\n";
} else {
length -= 1;
for (; i < length; i++) {
array2[i] = array2[i + 1];
}
}
cout << "Testing OP in deleteElement\n";
for (i = 0; i < length; i++) {
cout << array2[i] << " ";
}
}
If you use the algorithm function std::remove, you can accomplish this in one or two lines of code without writing any loops whatsoever.
#include <algorithm>
#include <iostream>
void deleteElement(int array2[], int& length, int element)
{
int *ptr = std::remove(array2, array2 + length, element);
length = std::distance(array2, ptr);
}
int main()
{
int array1[] = { 1, 4, 3, 5, 6 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, length, 4);
for (int i = 0; i < length; ++i)
std::cout << array1[i];
}
Output:
1356
Note that we could have written the deleteElement function in a single line:
void deleteElement(int array2[], int& length, int element)
{
length = std::distance(array2, std::remove(array2, array2 + length, element));
}
Basically, std::remove moves the removed element to the end of the sequence, and returns a pointer to the beginning of the removed elements.
Thus to get the distance from the beginning of the array to where the removed elements are located, usage of std::distance is done to give us our new length.
To remove only the first found element, std::find can be used, and then std::copy over the elements, essentially wiping out the item:
void deleteElement(int array2[], int& length, int element)
{
int *ptr = std::find(array2, array2 + length, element);
if ( ptr != array2 + length )
{
std::copy(ptr+1,array2 + length, ptr);
--length;
}
}
int main()
{
int array1[] = { 1, 4, 3, 5, 4, 6, 9 };
int length = sizeof(array1) / sizeof(array1[0]); //For length of array
deleteElement(array1, length, 4);
for (int i = 0; i < length; ++i)
std::cout << array1[i];
}
Output:
135469
There is no need for multiple loops in deleteElement. Additionally, your removal will fail to remove all elements (e.g. 4 in your example) if your array contains more than one 4, e.g.
int array1[] = { 1, 4, 3, 4, 5 };
You can simplify your deleteElement function and handle removing multiple occurrences of element simply by keeping a count of the number of times the element is found and by using your counter as a flag to control removal, e.g.:
void deleteElement(int array2[], int& length, int element)
{
int found = 0; /* flag indicating no. element found */
for (int i = 0; i < length; i++) { /* iterate over each element */
if (array2[i] == element) { /* check if matches current */
found += 1; /* increment number found */
continue; /* get next element */
}
if (found) /* if matching element found */
array2[i-found] = array2[i]; /* overwrite elements to end */
}
length -= found; /* update length based on no. found & removed */
}
Updating your example main() to show both pre-delete and post-delete, you could do something like the following:
int main (void) {
int array1[] = { 1, 4, 3, 4, 5 };
int length = sizeof array1 / sizeof *array1; //For length of array
cout << "\nBefore Delete\n";
for (int i = 0; i < length; i++)
cout << " " << array1[i];
cout << '\n';
deleteElement(array1, length, 4);
cout << "\nAfter Delete\n";
for (int i = 0; i < length; i++)
cout << " " << array1[i];
cout << '\n';
}
Example Use/Output
Which in the case where you array contains 1, 4, 3, 4, 5 would result in:
$ ./bin/array_del_elem
Before Delete
1 4 3 4 5
After Delete
1 3 5
While you are using an array of type int (of which there are many in both legacy and current code), for new code you should make use of the containers library (e.g. array or vector, etc...) which provide built in member functions to .erase() elements without you having to reinvent the wheel.
Look things over and let me know if you have further questions.
This is because the length of the array is never updated after deleting. Logically the length should decrease by 1 if the element was deleted.
To fix this, either
Pass the length by reference and decrease it by 1 if the element is actually deleted. OR
Return from the deleteElement some value which indicates that the element was deleted. And based of that, decrease the value of length in the main function.
Recalculating the array length will not help because the element is not actually deleted in memory. So the memory allocated to he array remains same.
Other issues:
The first for loop in deleteElement should run till j < length - 1.
The for loop creates a local variable i, which shadows the i variable in outer scope, so the outer i is never updated and always remains = 0

Regarding pointers and arrays and how they are assigned in memory in C++

So I am trying to solve this question:
Data is fed in the following input format. The first line contains two space-separated integers denoting the number of variable-length arrays, n, and the number of queries, q. Each line of the subsequent lines contains a space-separated sequence in the format
k Ai[0] Ai[1] … Ai[k-1]
where k is the length of the array, Ai, and is followed by the k elements of Ai. Each of the subsequent lines contains two space-separated integers describing the respective values of array number (ranging from 0 to n-1) and index in that particular array (ranging from 0 to ki) for a query. i.e, Given the following input:
3 3
3 1 2 3
5 4 5 6 7 8
4 9 10 11 12
0 1
1 3
2 0
This output is expected
2
7
9
I am basically a beginner in C++. This is the code I have tried but I feel the address at which each subsequent array is stored is giving me some problems
int main(){
int n, q;
scanf("%d %d", &n, &q);
printf("n,q = %d, %d\n", n, q);
int* row[n];
for (int i = 0; i < n; i++){
int k;
scanf("%d", &k);
printf("k = %d\n", k);
int col[k];
row[i] = col;
for (int j = 0; j < k; j++){
int elem;
scanf("%d", &elem);
printf("i,j,elem = %d, %d, %d\n", i, j, elem);
col[j] = elem;
cout << "address is " << &(col[j]) << "\n";
}
}
for (int query = 1; query <= q; query++){
int i, j;
scanf("%d %d", &i, &j);
int answer;
answer = *(row[i] + j);
printf("row[%d][%d] is %d\n", i, j, answer);
cout << "address is " << &answer << "\n";
}
return 0;
}
And this is the output produced:
n,q = 3, 3
k = 3
i,j,elem = 0, 0, 1
address is 0x7ffe236edb70
i,j,elem = 0, 1, 2
address is 0x7ffe236edb74
i,j,elem = 0, 2, 3
address is 0x7ffe236edb78
k = 5
i,j,elem = 1, 0, 4
address is 0x7ffe236edb60
i,j,elem = 1, 1, 5
address is 0x7ffe236edb64
i,j,elem = 1, 2, 6
address is 0x7ffe236edb68
i,j,elem = 1, 3, 7
address is 0x7ffe236edb6c
i,j,elem = 1, 4, 8
address is 0x7ffe236edb70
k = 4
i,j,elem = 2, 0, 9
address is 0x7ffe236edb60
i,j,elem = 2, 1, 10
address is 0x7ffe236edb64
i,j,elem = 2, 2, 11
address is 0x7ffe236edb68
i,j,elem = 2, 3, 12
address is 0x7ffe236edb6c
row[0][1] is 32766
address is 0x7ffe236edbcc
row[1][3] is 32766
address is 0x7ffe236edbcc
row[2][0] is 3
address is 0x7ffe236edbcc
Basically, I find that the array addresses are overlapping. Also, The answer computation by dereferencing is resulting in unexpected outputs. Any explanation to the mistakes made here would be appreciated.
Here is a major problem:
for (int i = 0; i < n; i++){
...
int col[k];
row[i] = col;
...
}
The variable col has its scope only inside the loop. Once the loop iterates the variable cease to exist. Storing a pointer to it will lead to undefined behavior when you try to dereference the pointer.
The simple solution is probably to dynamically allocate memory for col using malloc.
Missed that the question was tagged C++, and confused because the source doesn't actually use any C++-specific code. This kind of makes it worse since variable-length arrays are not part of C++. Some compilers have it as an extension, but you should not use it when programming in C++.
Instead you should be using std::vector and then you can easily solve your problem without your own dynamic allocation. Then you can make row a vector of vectors of int and col a vector of int, and then the assignment will work fine (if row have been set to the correct size of course).
An easy way to use C++ without getting too many memory management bugs is to use standard library types. Leave the bare metal stuff to the poor C guys who do not have that ;)
So instead of meddling with new[] and delete[], use types like std::vector<> instead.
The "modern C++" version below uses iostream for no good reason. Old stdio.h is sometimes the preferred choice and so is sometimes iostream. And sometimes it is just a matter of style and taste.
#include <vector>
#include <iostream>
#include <fstream>
typedef struct Q
{
int iArray;
int iIndex;
} Q_t;
typedef std::vector<std::vector<int> > Data_t;
typedef std::vector<Q_t> Query_t;
bool Load(Data_t& data, Query_t &queries, std::istream& is)
{
size_t ndata = 0;
size_t nqueries = 0;
is >> ndata;
is >> nqueries;
data.resize(ndata);
queries.resize(nqueries);
for (size_t d = 0; d < ndata; d++)
{
size_t l = 0;
is >> l;
data[d].resize(l);
for (size_t i = 0; i < l; i++)
{
is >> data[d][i];
}
}
for (size_t q = 0; q < nqueries; q++)
{
is >> queries[q].iArray;
is >> queries[q].iIndex;
}
return true;
}
int main(int argc, const char * argv[])
{
std::ifstream input("E:\\temp\\input.txt");
Data_t data;
Query_t queries;
if (Load(data, queries, input))
{
for (auto &q : queries)
{
std::cout << data[q.iArray][q.iIndex] << std::endl;
}
}
return 0;
}
The mistake is, you have used 'col' array which loses its scope after completion of for loop. The way you can fix this is by either using dynamic memory allocation or by declaring it outside the for loop
Hope the below code will help you get an idea :)
#include <cmath>
#include <cstdio>
#include <vector>
#include <iostream>
#include <algorithm>
using namespace std;
int main() {
int n, q;
cin >> n;
cin >> q;
int* row[n];
int* col;
for(int i=0; i<n; i++)
{
int k;
cin >> k;
col = new int[k];
row[i] = col;
for(int j=0; j<k; j++)
{
cin >> col[j];
}
}
for(int query=0; query<q; query++)
{
int i,j;
cin >> i;
cin >> j;
cout << row[i][j] << endl;
}
delete[] col;
return 0;
}

Finding the highest number in an array of length 5

This should be really simple, but I'm used to higher level languages and am missing something. I'm just trying to make sure the input is five numbers long, and then find the highest number. Unfortunately, something goes wrong in that second part.
#include <iostream>
#include <string>
bool isFiveDigits(int num) {
if (std::to_string(num).length() == 5) {
return true;
} else {
return false;
}
}
int highestInArr(int *nums) {
int highest = nums[0];
for (int i = 1; i < sizeof(nums); i++) {
int temp = nums[i];
if (temp > highest) {
highest = temp;
}
}
return highest;
}
int main() {
using namespace std;
int num;
int nums [5];
cout << "Enter a five digit number!\n";
cin >> num;
if (!isFiveDigits(num)) {
cout << "Not five digits, can you even count?";
return 1;
}
string numstr = to_string(num);
for (int i = 0; i < numstr.length(); i++) {
cout << numstr[i] << " ";
nums[i] = (int)numstr[i];
}
cout << "\n" << highestInArr(nums);
}
When this runs, I get:
Enter a five digit number!
12345
1 2 3 4 5
1424080487
Of course, 1,424,080,487 is not in [1, 2, 3, 4, 5].
You cannot pass a pointer into a function and get the size of it without template deduction. At runtime, all the function receives is a pointer. When you call sizeof(nums), you are not getting the size of the original array. You are simply getting the size of the pointer, which is the same as saying sizeof(int_ptr). Instead, you should be using a std::vector when using collections whose sizes are dynamic.
Now, you CAN receive the size by doing something like this:
#include <iostream>
template<typename num_t, size_t N>
num_t max_num(num_t(&arr)[N]) {
num_t m = (num_t)0;
for (size_t i = 0; i < N; ++i)
if (arr[i] > m)
m = arr[i];
return m;
}
int main(){
int foo[] = { 1, 5, 2, 4, 3 };
int m = max_num(foo);
std::cout << m << std::endl;
std::cin.get();
return 0;
}
However, this is not necessarily preferred and assumes that the array was created on the caller's stack. It does not work for dynamically allocated arrays that were created with new[]. If you do this multiple times with different sizes, you will have multiple implementations of the same function (that's what templates do). The same goes for using an std::array<int, N>. If you use N as a size_t template parameter, it will do the same thing.
There are two preferred options:
Send the size of the array into the function so that the caller is responsible for the size.
Use a different container such as std::vector so the callee is responsible for the size.
Example:
#include <vector>
#include <iostream>
#include <algorithm>
int main(){
std::vector<int> vec{ 1, 5, 2, 4, 3 };
int m = *std::max_element(std::cbegin(vec), std::cend(vec));
std::cout << m << std::endl;
std::cin.get();
return 0;
}
As for the is_5_digits, you should use the base-10 logarithm function.
#include <cmath>
// ...
int i = 12345;
size_t length = (i > 0 ? (int)log10(i) : 0) + 1;
std::cout << length << std::endl; // prints 5;
First of all, you can't simply convert a char to int just like (int)numstr[i] assuming that it will return the digit which it contains.
See, if you have a char '0', it means it's ASCII equivalent is stored, which is 48 in case of 0, 49 in case of '1' and so on.
So in order to get that digit (0,1,2,...,9), you've to substract 48 from the ASCII value.
So change this line:
nums[i] = (int)numstr[i];
to:
nums[i] = (int)numstr[i] - 48; // or nums[i] = (int)numstr[i] - '0';
And another thing, in your highestInArr function, you're getting a pointer as parameter, and in the function, you're using sizeof to determine the size of the array. You can't simply do that, the sizeof will return the size of int*, which is not the size of the array, so you've to pass size as the second argument to the function, and use it in the loop.
Like this:
int highestInArr(int *nums, int size) {
// ...
for (int i = 1; i < size; i++) {
// ...
}
// ...
}

Sorting an array to another array C++

My program have to sort an array in another array.
When I run the program it prints 1 2 3 -858993460 5 -858993460 7.
I can not understand where the mistake is in the code.
#include <iostream>
using namespace std;
int main()
{
const int N = 7;
int arr[N] = { 3, 17, 2, 9, 1, 5, 7 };
int max = arr[0];
for (int i = 1; i < N; i++)
{
if (max < arr[i])
max = arr[i];
}
int sort_arr[N];
for (int j = 0; j < N; j++)
{
sort_arr[arr[j] - 1] = arr[j];
}
for (int i = 0; i < N; i++)
{
cout << sort_arr[i] << " ";
}
return 0;
}
Okay lets face the problems in your code.
The "weird" numbers you see there, came from the uninitialzied array sort_arr. What do I mean by uninitialized? Well sort_arr is a little chunck somewhere in your memory. Since a program usually does not clear its memory and rather claims the memory it used as free, the chunk of sort_arr may contain bits and bytes set by another program. The numbers occure since these bytes are interpreted as an integer value. So the first thing to do would be to initialize the array before using it.
sort_arr[N] = { 0, 0, 0, 0, 0, 0, 0 };
Now why did these numbers occure? Well you're probably expecting your algorithm to set all values in sort_arr which would result in an sorted array, right? Well but your algorithm isn't working that well. See this line:
sort_arr[arr[j] - 1] = arr[j];
What happens when j is 1? arr[1] is then evaluated to 17 and 17 - 1 equals 16. So sort_arr[arr[1] - 1] is the same as sort_arr[16] which exceeds the bounds of your array.
If you want to program a sorting algorithm by your self than I would recommend to start with an simple bubble sort algorithm. Otherwise, if you only need to sort the array have a look at the algorithm header. It is fairly simple to use:
#include <iostream>
#include <algorithm>
#include <iterator> // << include this to use begin() and end()
using namespace std;
int main()
{
const int N = 7;
int arr[N] = { 3, 17, 2, 9, 1, 5, 7 };
int sort_arr[N] = { 0, 0, 0, 0, 0, 0, 0 };
copy(begin(arr), end(arr), begin(sort_arr));
sort(begin(sort_arr), end(sort_arr));
for (int i = 0; i < N; i++)
{
cout << sort_arr[i] << " ";
}
cout << endl;
}
By the way. You're looking for the biggest value in your array, right? After you have sorted the array sort_arr[N - 1] is the biggest value contained in your array.
If you want to sort a array into another array then one way is you make a copy of the array and then use the sort function in the standard library to sort the second array.
int arr[10];
int b[10];
for(int i=0;i<10;i++)
{
cin>>arr[i];
b[i]=arr[i];
}
sort(b,b+10);
// this sort function will sort the array elements in ascending order and if you want to change the order then just add a comparison function as third arguement to the sort function.
It seems that you think that sort_arr[arr[j] - 1] = arr[j] will sort arr into sort_arr. It won't.
Sorting is already written for you here: http://en.cppreference.com/w/cpp/algorithm/sort You can use that like this:
copy(cbegin(arr), cend(arr), begin(sort_arr));
sort(begin(sort_arr), end(sort_arr));
Live Example
My guess is this is an attempt to implement a type of counting sort. Note that variable length arrays aren't normally allowed in C++ or some versions of C. You could use _alloca() to allocate off the stack to get the equivalent of a variable length array: int * sort_arr = (int *)_alloca(max * sizeof(int)); .
#include <iostream>
using namespace std;
int main()
{
const int N = 7;
// assuming range of values is 1 to ...
int arr[N] = { 3, 17, 2, 9, 1, 5, 7 };
int max = arr[0];
for (int i = 1; i < N; i++)
{
if (max < arr[i])
max = arr[i];
}
int sort_arr[max];
for (int i = 0; i < max; i++)
{
sort_arr[i] = 0;
}
for (int j = 0; j < N; j++)
{
sort_arr[arr[j] - 1]++;
}
for (int i = 0; i < max; i++)
{
while(sort_arr[i])
{
cout << i+1 << " ";
sort_arr[i]--;
}
}
return 0;
}

Reverse Array in C++

I have successfully reversed a 1-D array but when I cout the contents, it prints out the contents then bunch of other numbers.
4
3
2
1
-858993460
-858993460
4
-858993460
-1021245226
12384668
3697177
1
14484784
14501672
-1021245434
0
Press any key to continue . . .
I can't tell why it's printing out those extra numbers. Below is my source code:
#include <iostream>
#include <array>
using namespace std;
void flipRow(int array[], int row) {
int temp;
for (int i = 0; i < sizeof(array)/2; i++) {
//cout << "Hi" << endl;
temp = array[i];
array[i] = array[row-1];
array[row-1] = temp;
row--;
}
}
int main() {
const int ROW = 4;
int array[ROW] = { 1, 2, 3, 4 };
flipRow(array, ROW);
for (int i = 0; i < sizeof(array); i++) {
cout << array[i] << endl;
}
system("pause");
return 0;
}
Are those addresses? Can someone tell why it's printing them out? Thank you.
Modify your for loop in main so the condition part of it becomes i < ROW and modify the for loop in flipRow so the condition part there reads i < row/2. sizeof operator returns the size of your array in bytes. You have four elements in your array and they are of type integer, which on your platform is 4 bytes, so your call to sizeof is returning 16.