Undefined behaviour or may be something with memset - c++

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;
// ...
}

Related

Iterating over a vector

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;

Run time error for non increasing value of a int recursively C++

Here is my code. I'm getting a run time error. Is there a better way to procede recursively?
The goal is: taking 3 as the input will result this
1 1 1
2 1
3
If there is a better way to implement easy recursion, i'm listening
#include <iostream>
using namespace std;
int divide(int input,int memory) {
if(memory==input){
cout<<input;
exit(1);
}
cout<<memory<<" ";
int i=memory;
for(i;i<input;i++){
cout<<1<<" ";
}
cout<<endl;
memory++;
divide(input,memory);
}
int main() {
// your code goes here
divide(8,1);
return 0;
}
You simply get a runtime error because of this line:
exit(1);
Change it to:
exit(0);
Btw, if you just want to stop the function when input==memory instead use:
return 0;
EDIT: int divide(int input,int memory) { this means you must return an int. If you don't really need to return anything, change it to:
void divide(int input,int memory) {
and use: return; to stop the recursion
EDIT: Since you asked a cleaner implementation (in my opinion) would be:
void divide(int input,int memory) {
std::vector<int> result(input - memory + 1, 1);
result.front() = memory;
std::copy(result.begin(), result.end(), std::ostream_iterator<int>(std::cout, " "));
std::cout << endl;
if (input < ++memory) return;
divide(input,memory);
}

Random array value after return c++

My problem is I don't know what happens with data that I put into my arrays and how to make them stay in array. While debugging it is clear that arr gets initialized with zeros and arr2 with {1,2,3}. Functions however return some random values.. can someone help me to point out what it should be like?
#include <iostream>
#include <algorithm>
#include <vector>
class A
{
private:
double arr[5];
public:
A()
{
std::fill( arr, arr + 5, 0.0 );
};
~A() {};
void setArr( double arrx[] )
{
for ( int i = 0; i < 5; i++ )
arr[i] = arrx[i];
}
double* getArr(void) { return arr;}
};
int* probe()
{
int arr2[3] = {1,2,3};
return arr2;
}
int main()
{
A ob1;
double rr[5] = {1,2,3,4,5};
ob1.setArr(rr);
std::cout << ob1.getArr() << std::endl;
std::cout << probe() << std::endl;
system("Pause");
}
EDIT:
Now thanks to you i realize I have to loop the get** function to obtain all values. But how can I loop it if my planned usage is to write it like you see below into some file?
pF = fopen ("myfile.csv","a");
if (NULL != pF)
{
char outp[1000];
sprintf_s(outp, 1000, "%6d,\n", ob1.getArr());
fputs(outp, pF);
fclose(pF);
}
In
std::cout << ob1.getArr() << std::endl;
std::cout << probe() << std::endl;
You are actually printing the pointers (address), not the values which are double or int. You need to loop through all the elements of the array to print them.
As pointed out by P0W that accessing element of probe() has undefined behaviour, in that case you must make sure that the array should be valid. One quick solution is that declare the array static in the function.
As you want to write the value in the file
pF = fopen ("myfile.csv","a");
if (NULL != pF)
{
char outp[1000];
int i;
int retsofar=0;
for(i=0;i<5;++i)
retsofar+=sprintf_s(outp+retsofar, 1000-retsofar, "%6d,\n", ob1.getArr()[i]);
fputs(outp, pF);
fclose(pF);
}
you are trying to print the addresses of arrays returned by ob1.getArr() and probe() methods. Every time you are getting different addresses. If you want to print array, use loop.
In probe(), you are creating an array on stack and simply returning it's pointer. It is not safe. When it goes out of scope, its values can be overwritten and you may get un expected behaviour. So create that array on heap.

Run time error for dynamic memory allocation in C++

I am a newbie for OOP concepts and while trying to solve Project Euler Problem 7, to find 10001th prime number, I tried to do it using a class but encountered 2 major errors.
instantiating the class prime_n
initializing its argument
I have posted the code here for reference:
#include<iostream>
#include<cstdio>
using namespace std;
class prime_n
{
int j,k;
int n;
int *store;
public:
prime_n(int num)
{
n=num;
store[n];
}
static int isPrime(int j)
{
for(int i=2;i*i<=j;i++)
{
if(j%i==0) return 0;
}
return 1;
}
void find_n()
{
for(int i=0;i<n;i++)
{
store[i]=0;
}
store[0]=2;
j=3;
k=1;
while(store[n-1]==0)
{
if(isPrime(j)) store[k++]=j;
j+=2;
}
}
int get_num()
{
int value=store[n-1];
return value;
}
};
int main()
{
int num, req_num;
printf("Enter the position at which prime number is to be found ");
scanf("%d",&num);
printf("\nnumber = %d",num);
prime_n p = new prime_n(num);
req_num = p.get_num();
printf("The required prime number is %d\n",req_num);
return 0;
}
It would be a great help if someone could help me figure out where I am actually going wrong. Thanks a lot in advance!
Use
prime_n p(num);
or (not recommended in this particular case)
prime_n * p = new prime_n(num);
// some other code
req_num = p->get_num(); // note the -> operator replacing . in case of pointers
delete p;
The first case declares p on stack and it is automatically deallocated when the program leaves the scope (main function in this case)
The second one allocates space on heap and p is the pointer to it. You have to deallocate the memory manually.
As for your second question, the C++ way would be
#include <iostream>
...
int num;
std::cout << "Enter the position at which prime number is to be found "
std::cin >> num;
std::cout << std::endl << "Number = " << num << std::endl;
You provide a constructor:
prime_n(int num)
{
n=num;
store[n];
}
I think you are under the impression that store[n] creates an array with n elements, but that is not so; it attempts to access the (n+1)th element of an an array. Since store does not point anywhere (we are in the constructor, after all), the program crashes.
You probably want to write store = new int[num] instead.
And then I cannot see any call to find_n() originating from get_num() which is called in main(), so that your program would for now just return a random value.

How do I do something like this some_function({1,1,1,1})?

Lets say I have a function with prototype like this: int func(int * a), and it accepts an array as an argument.
How do I do this without the compiler showing errors everywhere: func({1,1,1,1})
Like this:
int func(int * a);
void somewhere_else()
{
int arr[4] = { 1, 1, 1, 1 };
func(arr);
}
Don't use raw arrays, and certainly don't pass pointers to them into functions. Ew! We're not in 1975 any more.
#include <cstddef>
#include <iostream>
#include <vector>
void func(std::vector<int> const& v) {
for (std::size_t i = 0; i < v.size(); i++)
std::cout << v[i] << " ";
}
int main() {
func({ 1, 2, 3, 4 });
}
// Output: "1 2 3 4 "
This requires a compiler that is compliant with certain features of C++11. Namely initializer lists.
You can use std::initializer_list:
int func(std::initializer_list<int> a) {
// do something with a here
}
Or you can write a wrapper that uses std::initializer_list (if for some reason you cannot change the original function):
int func_wrapper(std::initializer_list<int> a) {
std::vector<int> b = a;
func(b.data());
}
one way to do that would be
#include <iostream>
#include <stdio.h>
void abc (int *a,int z)
{
int m= z/sizeof(*a);
for(int i=0;i<m;i++)
{
std::cout<<"values " <<*a<<"\n";
a++;
}
}
int main()
{
int ar[]={11,12,13,14,15,1166,17};
std::cout << sizeof(ar)<<"size\n";
abc(ar,sizeof(ar));
getchar();
}
here in this case you dont need to worry about size and all. In case of
int ar[3]={1,2,3} that will give junk values if you try and search for NULL as
the third place is occupied by element 3
All you need is an (int[]) cast:
#include <iostream>
static void f (int* a) {
while (*a) std::cout << *a++ << "\n" ;
}
int main() {
f ((int[]){1,2,3,4,0}) ;
}
This code outputs
1
2
3
4
It works in C too -- see this ideone link.
Updated to add: I posted a new question about the legality of this construct, and Mat's answer is worth reading if you're interested in that kind of thing. Briefly, it seems that it is valid only in C99, but that some compilers allow it as an extension in all C/C++ variants.