I am trying to create a dynamically allocated array and print it's contents in C++. Although my code is producing incredibly strange output when I print.
int main() {
int* arr;
arr = new int [1200];
memset(arr, 5, 1200);
for (int i = 0; i < 1200; i++)
printf("%d ", arr[i]);
std::cout << '\n';
return 0;
}
Mixing the cout and printf was just because I was playing around with the code. All the proper includes are in my file.\
Here is the output:
84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 84215045 1285 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0
I have no idea how this was produced.
EDIT:
Thank you everyone for the answers. I now understand what my code does and why the output looks the way that it look.Great answers.
memset(arr, 5, 1200);
If you scribble a whole bunch of 5'a on a piece of paper and then try to read the paper, you'll get back things like "5555". 84215048 in hex is 0x05050505.
Don't manipulate arrays of data as if they were raw chunks of memory unless you know exactly what you're doing.
Your code is setting each byte in the first part of the array, to 5. With a modern C++ compiler as of 2014 each int is 4 bytes or 8 bytes, with each byte 8 bits (although on some computers it can be 16 bits per byte). Assuming 8 bits per byte and 4 bytes per int you'd get the value ((5×256 + 5)×256 + 5)×256 + 5 =
C:\> set /a ((5*256 + 5)*256 + 5)*256 + 5
84215045
C:\> _
Here's how to do your program in the most natural way in C++:
#include <iostream>
#include <vector>
using namespace std;
auto main() -> int
{
vector<int> arr( 1200, 5 );
for( int x : arr ) { cout << x << ' '; }
cout << '\n';
}
Consider 84215045 byte by byte in hex and you will understand what happened:
84215045 = 05050505 (hex)
memset initializes every byte to 5, but an integer is 4-byte long in your case. Also, memset expects the size in bytes of the memory region to fill, which is not 1200, but 1200 * sizeof (int), which in your case appears to be 4800. This explains the trailing zeroes as well.
You might initialize every element to 5 using a loop:
arr = new int [1200];
for (int i = 0; i < 1200; ++i) arr[i] = 0;
or with pointers:
arr = new int[1200];
for (int *cur = arr, *end = arr + 1200; cur < end; ++cur) *cur = 0;
Finally, consider doing away with direct allocation of arrays with new and using STL containers like std::vector if possible.
Related
I want to initialize the last 4 bytes of a char array with 0 (set all 32 bits to zero). But the assignment is changing only one byte in the array. How can I change this byte and the next three in a single command, instead of looping through all 4 bytes? Is this possible?
#include <iostream>
#include <iomanip>
using namespace std;
int main() {
char buf[8 + 4]; // 8 bytes of garbage + 4 = 32 safety bits
buf[8] = (uint32_t)0; // turns all safety bits into zero???
cout << hex << setfill(' ');
for (int i=0; i<8 + 4; i++) {
cout << setw(3) << (int)buf[i];
}
cout << dec << endl;
return 0;
}
That's displaying:
0 9 40 0 0 0 0 0 0 8 40 0
^ ^ ^ ^
ok garbage undesired
if you do not want to initialize the whole array, you can use memset or a similar function.
#include <string.h>
...
memset(&buf[8], 0, 4);
based on the comments, i added the a more c++like way to do the same:
#include <algorithm>
...
std::fill(&a[8],&a[8+4],0);
There is also another option:
*(uint32_t*)(&buf[8]) = 0;
Or, more c++ way:
#include <algorithm>
std::fill(buf + 8, buf + 12, 0);
How would I change an array of bit sets to a 1d array of ints with each element holding only 1 digit in C++. for example, i have bitset<8> bitArray[n], and I want to bit into int binArray[8*n], where binArray holds something like [0],[1],[1],[0],[1],[0] and so forth.
You can use an std::bitset::operator[] to access the specifit bit. Keep in mind though, that [0] means the least significant bit, but we want to store them in the most significant -> least significant order, so we have to use the 7 - j instead of simply j:
#include <iostream>
#include <bitset>
int main()
{
constexpr int SIZE = 5;
std::bitset<8> bitArray[SIZE] = {3, 8, 125, 40, 13};
int binArray[8 * SIZE];
for(int i = 0, index = 0; i < SIZE; ++i){
for(int j = 0; j < 8; ++j){
binArray[index++] = bitArray[i][7 - j];
}
}
}
The binArrays content looks like so (newlines added by me to improve readability):
0 0 0 0 0 0 1 1
0 0 0 0 1 0 0 0
0 1 1 1 1 1 0 1
0 0 0 0 1 1 0 1
Simply construct an array:
std::array<int, 8*n> binArray;
size_t out = 0;
for (const auto& bits : bitArray)
for (size_t ii = 0; ii < n; ++ii)
binArray[out++] = bitArray[ii];
I am trying to switch cols and rows of a 2D array by using a temp array and replace original array with temp using std::copy at the end. But std::Copy copying only first row and rest are showing same old values in original array. Also the statement array = {}; is not clearing indexes to 0.
// Clear array to 0 (issue: This has no effect at all)
array[arrayRowSize][arrayColSize] = {};
// Copy array (issue: only first row is copied, rest of original still has old values)
std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);
Can anyone take a look at my code and tell me what I am doing wrong ? Please add some details about how it actually work, and suggest if there is anything we can improve.
#include <iostream>
#include <cstdint>
using namespace std;
bool IsIntegerInputValid (int16_t arrayData, int8_t arrayLimit)
{
// Entered input is a non-digit, negative number or > arrayLimit ?
if ( cin.fail() || arrayData < 0 || arrayData > arrayLimit )
{
// Clear error flag and input buffer
cin.clear();
cin.ignore();
cout << "Invalid input, Please try again" << endl;
return false;
}
return true;
}
int main()
{
const uint8_t kMaxArraySize = 10;
int16_t array[kMaxArraySize][kMaxArraySize] = {};
int16_t arrayRowSize = 0;
int16_t arrayColSize = 0;
// Get array size
while (1)
{
cin >> arrayRowSize;
if ( IsIntegerInputValid ( arrayRowSize, kMaxArraySize) )
{
while (1)
{
cin >> arrayColSize;
if ( IsIntegerInputValid ( arrayColSize, kMaxArraySize) )
{
break; // Got valid size
}
}
break; // Got valid size
}
}
// Get array input
for (int i = 0; i < arrayRowSize; ++i)
{
for (int j = 0; j < arrayColSize; ++j)
{
cin >> array[i][j];
if ( !IsIntegerInputValid (array[i][j], kMaxArraySize) )
{
--i; // Try again
}
}
}
// Copy rows to cols and cols to rows
int16_t tempArray[kMaxArraySize][kMaxArraySize] = {};
for (int i = 0; i < arrayColSize; ++i)
{
for (int j = 0; j < arrayRowSize; ++j)
{
tempArray[i][j] = array[j][i];
cout << tempArray[i][j] << ' ';
}
cout << endl;
}
array[arrayRowSize][arrayColSize] = {}; // Clear array to 0 (issue: This has no effect at all)
// Copy array (issue: only first row is copied, rest of original still has old values)
std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);
return 0;
}
Thanks
array[arrayRowSize][arrayColSize] = {}; // Clear array to 0 (issue: This has no effect at all)
This accesses the table element at next out of bounds row of array and next out of bounds column of that row (if the row had any column that werent out of bounds). The behaviour is undefined. The last index that can be accessed is array[arrayRowSize - 1][arrayColSize - 1]. Assigning to an element out of bounds does nothing along the lines of clearing the array.
To set all elements of an array to zero, I would use:
std::memset(array, 0, sizeof array);
That said, you're about to overwrite all values, so this appears to be pointless.
std::copy(&tempArray[0][0], (&tempArray[0][0])+arrayColSize*arrayRowSize, &array[0][0]);
This assumes that the lines are stored contiguously in memory. And if that were true, this would work just fine. However, since you've allocated A large array, and use only part of each row, there are unused parts of the rows between.
An example: You allocate a 7x7 array, then use only a 3x3 array within it. The memory layout could be following:
|-----| <- a row
AAAXXXXBBBXXXXCCCX...
|-------| <- first 9 elements
A represents first row, B represents second ...
X represents unused part of the array.
Now, if you copy 9 contiguous elements as if they were all elements of your array, you would get AAAXXXXBB, which contains plenty of unused elemnets, and not all of used elements.
Since your rows are not contiguous, you must copy each row separately. Or you could copy the entire array including the unused portions.
The copy doesn't work because sizes of your aray is not the same as kMaxArraySize.
copy tries to copy array as one dimensional array. but in your case 2d array coverted to 1d can have a lot of zeros inside.
if you've choosen size 3, 3 the your array will be like :
1 2 3 0 0 0 0 0 0 0
4 5 6 0 0 0 0 0 0 0
7 8 9 0 0 0 0 0 0 0
......
for 1d representation it will look like:
1 2 3 0 0 0 0 0 0 0 4 5 6 0 0 0 0 0 0 0 7 8 9 0 0 0 0 0 0
but copy will take only 9 first records.
I am writing a program that needs to take an array of size n and convert that into it's hex value as follows:
int a[] = { 0, 1, 1, 0 };
I would like to take each value of the array to represent it as binary and convert it to a hex value. In this case:
0x6000000000000000; // 0110...0
it also has to be packed to the right with 0's to be 64 bits (i am on a 64 bit machine).
Or i could also take the array elements, convert to decimal and convert to hexadecimal it that's easier... What you be the best way of doing this in C++?
(this is not homework)
The following assumes that your a[] will only ever use 0 and 1 to represent bits. You'll also need to specify the array length, sizeof(a)/sizeof(int) can be used in this case, but not for heap allocated arrays. Also, result will need to be a 64bit integer type.
for (int c=0; c<array_len; c++)
result |= a[c] << (63-c);
If you want to see what it looks like in hex, you can use (s)printf( "%I64x", result )
std::bitset<64>::to_ulong() might be your friend. The order will probably be backwards (it is unspecified, but typically index 3 will be fetched by right-shifting the word by 3 and masking with 1), but you can remedy that by subtracting the desired index from 63.
#include <bitset>
std::bitset<64> bits;
for ( int index = 0; index < sizeof a/sizeof *a, ++ index ) {
bits[ 63 - index ] = a[ index ];
}
std::cout << std::hex << std::setw(64) << std::setfill('0')
<< bits.to_ulong() << std::endl;
unsigned long long answer= 0;
for (int i= 0; i<sizeof(a)/sizeof(a[0]); ++i)
{
answer= (answer << 1) | a[i];
}
answer<<= (64 - sizeof(a)/sizeof(a[0]));
Assumptions: a[] is at most 64 entries, is defined at compile time, and only contains 1 or 0. Being defined at compile time sidesteps issues of shifting left by 64, as you cannot declare an empty array.
Here's a rough answer:
int ConvertBitArrayToInt64(int a[])
{
int answer = 0;
for(int i=0; i<64; ++i)
{
if (isValidIndex(i))
{
answer = answer << 1 | a[i];
}
else
{
answer = answer << 1;
}
}
return answer;
}
byte hexValues[16];
for(int i = 15; i >= 0; i--)
{
hexValues = a[i*4] * 8 + a[i*4-1] * 4 + [i*4-2] * 2 + a[i*4-3];
}
This will give you an array of bytes where each byte represents one of your hex values.
Note that each byte in hexValues will be a value from 0 to 16.
I'm trying to work with vectors of vectors of ints for a sudoku puzzle solver I'm writing.
Question 1:
If I'm going to access a my 2d vector by index, do I have to initialize it with the appropriate size first?
For example:
typedef vector<vector<int> > array2d_t;
void readAPuzzle(array2d_t grid)
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
cin >> grid[i][j];
return;
}
int main()
{
array2d_t grid;
readAPuzzle(grid);
}
Will seg fault. I assume this is because it is trying to access elments of grid that have not yet been initialized?
I've swapped out grid's declaration line with:
array2d_t grid(9, vector<int>(9, 0));
And this seems to get rid of this seg fault. Is this the right way to handle it?
Question 2:
Why is it that when I try to read into my grid from cin, and then print out the grid, the grid is blank?
I'm using the following code to do so:
void printGrid(array2d_t grid)
{
for (int i = 0; i < 9; i++)
{
for (int j = 0; j < 9; j++)
{
cout << grid[i][j] + " ";
}
cout << endl;
}
}
void readAPuzzle(array2d_t grid)
{
for(int i = 0; i < 9; i++)
for(int j = 0; j < 9; j++)
cin >> grid[i][j];
return;
}
int main()
{
array2d_t grid(9, vector<int>(9, 0));
printGrid(grid);
readAPuzzle(grid);
printGrid(grid);
}
And I attempt to run my program like:
./a.out < sudoku-test
Where sudoku-test is a file containing the following:
3 0 0 0 0 0 0 0 0
5 8 4 0 0 2 0 3 0
0 6 0 8 3 0 0 7 5
0 4 1 0 0 6 0 0 0
7 9 0 0 2 0 0 5 1
0 0 0 9 0 0 6 8 0
9 3 0 0 1 5 0 4 0
0 2 0 4 0 0 5 1 8
0 0 0 0 0 0 0 0 6
The first call to printGrid() gives a blank grid, when instead I should be seeing a 9x9 grid of 0's since that is how I initialized it. The second call should contain the grid above. However, both times it is blank.
Can anyone shed some light on this?
Q1: Yes, that is the correct way to handle it. However, notice that nested vectors are a rather inefficient way to implement a 2D array. One vector and calculating indices by x + y * width is usually a better option.
Q2A: Calculating grid[i][j] + " " does not concatenate two strings (because the left hand side is int, not a string) but instead adds the numeric value to a pointer (the memory address of the first character of the string " "). Use cout << grid[i][j] << " " instead.
Q2B: You are passing the array by value (it gets copied) for readAPuzzle. The the function reads into its local copy, which gets destroyed when the function returns. Pass by reference instead (this avoids making a copy and uses the original instead):
void readAPuzzle(array2d_t& grid)