I'm trying to complete some code for an homework.
It involves (among other things) iterating over a vector and I'm getting a strange result.
main.cpp
#include "tp1.hpp"
int main(int argc, char** argv) {
std::vector<uint8_t> signal { 1,2,0,0,1,2,1,0,2,1,2,1,0,0,0,1,2,1 };
std::vector<LZ77Code> code = lz77_encode(signal, 18, 9);
return 0;
}
tp1.hpp
inline std::vector<LZ77Code> lz77_encode(const std::vector<uint8_t>& vSignal, size_t N, size_t n1) {
std::vector<LZ77Code> vCode;
std::vector<uint8_t>::const_iterator vSignalIt; //Iterator for the vector in the parameters
vSignalIt = vSignal.begin();
while (vSignalIt != vSignal.end())
{
std::cout << *vSignalIt << std::endl;
vSignalIt++;
}
return vCode;
}
I'm getting this printed in the console as a result :
☺
Not really what I intended, you guessed it. I shortened the code to the bare minimum because It's been a while since I dealt with C++ and I feel like I'm making a trivial error. Let me know if you need more details.
Thanks for your time!
When you write uint8_t to cout, it treats it as a char. You need to cast to int.
std::cout << static_cast<int>(*vSignalIt) << std::endl;
Related
I just started C++ and now I'm making a simple program. But don't know how to fix this problem.
I'm not a native english speaker so some sentences may not be understandable.
int main()
{
char test[5][4] = { "abc", "def", "ghi", "jkl", "mno" };
for (int i = 0; i < 5; ++i)
std::cout << test[i] << "\t";
return 0;
}
with this simple code, I made a print function
void printTest(char* pArr)
{
for (int i = 0; i < 5; ++i)
std::cout << pArr[i] << "\t";
}
Then in my main function, I typed printTest(*test);
but the result was 'a b c d'
while my expectation was 'abc def ghi jkl mno'
So I fixed printTest function like below
(changed const char* test[5][4] = { ... }
in main function)
void printTest(const char** pArr)
{
for (int i = 0; i < 5; ++i)
std::cout << pArr[i] << "\t";
}
which worked well.
The problem is, I want to use strcpy_s fucntion also.
strcpy_s(test[0], "xyx"); like this.
As strcpy_s get char* for the first parameter (not const char*),
I think I need to use char* for my array, and print function.
While that thing cause a wrong printing issue.
Did i wrote something wrong in my printTest function?
Or Is there any way that I can use strcpy_s function with const char* parameter?
PS. I used std::string and made it as I expected.
But I want to have a understanding and control of Char array.
I don't think void printTest(const char** pArr) will work with
char test[5][4].
The c++ compiler should refuse something like
void printTest(const char** pArr);
char test[5][4];
printTest(test);
Because test is a pointer to char [4],
while printTest() expects a pointer to char *.
You may have interesting in this function:
void printTest2(const char (*pArr)[4] )
{
for (int i = 0; i < 5; ++i)
std::cout << pArr[i] << "\t";
std::cout << "\n";
}
And the const keyword tells compiler (and what more important, the reader of your code) that "you won't modify the contents of 'pArr'". So compiler will not allow you to strcpy to pArr[i]. And this will compile and run.
void printTest3(char (*pArr)[4] )
{
for (int i = 0; i < 5; ++i)
{
strcpy(pArr[i], "123");
std::cout << pArr[i] << "\t";
}
std::cout << "\n";
}
...
printTest3(test);
I think you are a but confused about he use of const. Don't worry, it's happened to pretty much every one.
What's important to understand is that a non-const variable can be implicitly cast to a const variable at any time, but the reverse is not possible.
For your function PrintTest()
// Here, the const char** declaration is correct, your function only prints pArr,
// and the caller should not expect the function to modify his precious data.
// Another thing to remember: pArr is valid (and thus constant) only within
// the scope of PrintTest(). It simply does not exist anywhere else.
void printTest(const char** pArr)
{
for (int i = 0; i < 5; ++i)
std::cout << pArr[i] << "\t";
}
// this naturally allows printing of const and non-const data, as one would expects.
const char const_strings[2][4] = { "abc", "def" };
printTest(const_strings); // works!
// Note that if printTest() required a non_const pointer, the line above
// would not compile.
// const_strings being const, there is no way to modify it using strcpy_s();
// The code below also works fine,
char modifiable_strings[2][4] = { "tuv", "xyz" };
printTest(modifiable_strings); // works!
strcpy_s(modifiable_strings[0], "abc"); // is OK, because modifiable is not const.
printTest(modifiable_strings); // works, with different output!
I think most of the work is done here, just a little detail is missing at the end. Read on.
I'm trying to write the glue code for using MurmurHash3 to hash big integers (mpz_t and mpz_class) of the GMP library in C++. I do this in order to later use them in a std::unordered_map<mpz_class, int>.
I want the code to compile in a useful way for 32 bit and for 64 bit systems and to be easily extensible when 128 bit systems are required. Therefor I've written the MurmurHash3_size_t() function which calls the right hash function of MurmurHash3 and then converts the result to size_t. I assume that size_t is of the correct bit size in terms of 32/64/128 bit systems. (I don't know if this assumption is useful.) This part of the code compiles nicely.
The problem arises when I want to define the std::hash function. I get a compiler error for my code (see comment in code). How to write these std::hash functions correctly and how to call them?
(click to view MurmurHash3.h)
File hash_mpz.cpp:
#include "hash_mpz.h"
#include <gmpxx.h>
#include "MurmurHash3.h"
size_t MurmurHash3_size_t(const void *key, int len, uint32_t seed) {
#if SIZE_MAX==0xffffffff
size_t result;
MurmurHash3_x86_32(key, len, seed, &result);
return result;
#elif SIZE_MAX==0xffffffffffffffff
size_t result[2];
MurmurHash3_x64_128(key, len, seed, &result);
return result[0] ^ result[1];
#else
#error cannot determine correct version of MurmurHash3, because SIZE_MAX is neither 0xffffffff nor 0xffffffffffffffff
#endif
}
namespace std {
size_t hash<mpz_t>::operator()(const mpz_t &x) const {
// found 1846872219 by randomly hitting digits on my keyboard
return MurmurHash3_size_t(x->_mp_d, x->_mp_size * sizeof(mp_limb_t), 1846872219);
}
size_t hash<mpz_class>::operator()(const mpz_class &x) const {
// compiler error in next statement
// error: no matching function for call to ‘std::hash<__mpz_struct [1]>::operator()(mpz_srcptr)’
return hash<mpz_t>::operator()(x.get_mpz_t());
}
}
Found a solution which works for me:
namespace std {
size_t hash<mpz_srcptr>::operator()(const mpz_srcptr x) const {
// found 1846872219 by randomly typing digits on my keyboard
return MurmurHash3_size_t(x->_mp_d, x->_mp_size * sizeof(mp_limb_t),
1846872219);
}
size_t hash<mpz_t>::operator()(const mpz_t &x) const {
return hash<mpz_srcptr> { }((mpz_srcptr) x);
}
size_t hash<mpz_class>::operator()(const mpz_class &x) const {
return hash<mpz_srcptr> { }(x.get_mpz_t());
}
}
Then you can use the hash function as follows:
#include <iostream>
#include <gmpxx.h>
#include <unordered_map>
#include "hash_mpz.h"
using namespace std;
int main() {
mpz_class a;
mpz_ui_pow_ui(a.get_mpz_t(), 168, 16);
cout << "a : " << a << endl;
cout << "hash(a): " << (hash<mpz_class> { }(a)) << endl;
unordered_map<mpz_class, int> map;
map[a] = 2;
cout << "map[a] : " << map[a] << endl;
return 0;
}
Output:
a : 402669288768856477614113920779288576
hash(a): 11740158581999522595
map[a] : 2
Comments are appreciated.
I was trying to save the binary equivalent of a 32 bit number in an array A. For testing my showbits() function , I choosed 8,9 when I came across this thing:
I am facing an unreasonable thing in my code when I am placing memset in the function showbits(),I am geting absurd integers while I expect an output something as
00000000000000000000000000001000
that is the binary equivalent of 8 . While when I place memset in the main() method, it works properly and gives me the right output.Am I going out of bounds(I cannot see it !) .
My code :
SHOWBITS:
void showbits(int A[32],int num)
{
int k=0;
memset(A,0,sizeof(A));
while(num>0)
{
A[k] = num&1;
k++;
num>>=1;
}
return ;
}
Note: I have placed memset in showbits ,and I am getting incorrect answers!
MAIN:
int main()
{
int A[32],i;
showbits(A,8);
for(i=31;i>=0;i--)
printf("%d",A[i]);
return 0;
}
Whole program for testing:
#include<stdio.h>
#include<algorithm>
#include<cstring>
using namespace std;
void showbits(int A[32],int num)
{
int k=0;
memset(A,0,sizeof(A));
while(num>0)
{
A[k] = num&1;
k++;
num>>=1;
}
return ;
}
int main()
{
int A[32],i;
showbits(A,8);
for(i=31;i>=0;i--)
printf("%d",A[i]);
return 0;
}
When I place that memset statement in Main method before showbits() , I am getting correct output!
EDIT
If someone is interested in what I am getting
398420075242008462686872420075219611920941961187434-2205336646196127610926869242
68672826866724200752000202903316219611874341961187478819611565142686716196182637
61961141748268665201000
The A[32] in the method is actually just a pointer to A. Therefore, sizeof is the size of *int. Take the following test code:
void szof(int A[32])
{
std::cout << "From method: " << sizeof(A) << "\n";
}
int main(int argc, char *argv[])
{
int B[32];
std::cout << "From main: " << sizeof(B) << "\n";
szof(B);
return 0;
}
which give the following output:
From main: 128
From method: 8
Thus, the memset sets fewer bits than you think.
You must pass A by reference
void showbits(int (&A)[32],int num)
See here for more details: C++ pass an array by reference
Avi explained the problem in your code already. Another possible solution is to use C++-style arrays, instead of C-style arrays and memset. Then there is no possibility of a memset length error. Also there is no loss of performance.
#include <array>
void showbits(std::array<int, 32> &A, int num)
{
A = {}; // set all entries to 0
// ...
}
int main()
{
std::array<int, 32> A;
// ...
}
The following code compiles and runs in Code::Blocks, but issues and error in VS2010:
"Undhandled exception at 0x770815de in test2.exe: 0xC0000005: Access violation writing to location 0x00000002."
I realise the code is sort of dangerous, it's basically prototyping an idea I have for another project. What I want to be able to do is pass a reference to any given number of ints followed by a value. Then put this value into the referenced ints and bob's your uncle. And it works, which is nice. But not in VS2010 which bothers me. I'm not the most experience with pointers, so I don't know if I'm doing something wrong or it's just this kind of operation is not something that VS2010 is fond of. Which is a problem because the project I'm testing this for is all in VS2010! So I need this to work for that!
EDIT: I'm sorry, I'm new to the Code:Blocks thing. I guess I should specify which compiler I use in Code::Blocks? :D I use the miniGW (or something) implementation of the GNU GCC Compiler (or something like that). I hope it makes sense to you experience Code::Blocks users!
#include <iostream>
#include <stdarg.h>
using namespace std;
void getMonkey(int Count, ... )
{
int test;
va_list Monkeys;
va_start(Monkeys, Count );
for(int i = 0; i < (Count / 2); i++ )
{
*va_arg(Monkeys, int*) = va_arg(Monkeys, int);
}
va_end(Monkeys);
}
int main()
{
int monkey1 = 0;
int monkey2 = 0;
int monkey3 = 0;
getMonkey(6, &monkey1, 2, &monkey2, 4, &monkey3, 5);
cout << monkey1 << " " << monkey2 << " " << monkey3;
return 0;
}
Turns out lvalues and rvalues are NOT evaluated in the order I assumed! TY stackoverflow!
Updated getMonkey method:
void getMonkey(int Count, ... )
{
int test;
va_list Monkeys;
va_start(Monkeys, Count );
for(int i = 0; i < (Count / 2); i++ )
{
int* tempMonkeyPtr = va_arg(Monkeys, int*); //herp
*tempMonkeyPtr = va_arg(Monkeys, int); //derp
}
va_end(Monkeys);
}
Yey! I'm getting a hang of this pointer business me thinks!
In a game that I mod for they recently made some changes which broke a specific entity. After speaking with someone who figured out a fix for it, they only information they gave me was that they "patched it" and wouldn't share anymore.
I am basically trying to remember how to dump the memory contents of a class object at runtime. I vaguely remember doing something similar before, but it has been a very long time. Any help on remember how to go about this would be most appreciated.
template <class T>
void dumpobject(T const *t) {
unsigned char const *p = reinterpret_cast<unsigned char const *>(t);
for (size_t n = 0 ; n < sizeof(T) ; ++n)
printf("%02d ", p[n]);
printf("\n");
}
Well, you may reinterpret_cast your object instance as a char array and display that.
Foo foo; // Your object
// Here comes the ugly cast
const unsigned char* a = reinterpret_cast<const unsigned char*>(&foo);
for (size_t i = 0; i < sizeof(foo); ++i)
{
using namespace std;
cout << hex << setw(2) << static_cast<unsigned int>(a[i]) << " ";
}
This is ugly but should work.
Anyway, dealing with the internals of some implementation is usually not a good idea.