C++ return std::pair<int *,int *>? - c++

#include <iostream>
#include <string>
#include <utility>
using namespace std;
string num1="123456789123456789";
std::pair<int*,int*> cpy(){
int a[(num1.size()%9==0)? num1.size()/9 : num1.size()/9+1];
int b[(num1.size()%9==0)? num1.size()/9 : num1.size()/9+1];
return make_pair(a,b);
}
int main(void){
return 0;
}
-------------------------------------------------------
//if by this style, it can be compiled
std::pair<int*,int*> cpy(){
const int N=5;
int a[5];
int b[5];
return make_pair(a,b);
}
I am writing a program to calculate Big Number such as 19933231289234783278, So I need split the number using 1 000 000 000 system
Why can't return a pair by this way?

You can't return a pair this way, because you are passing wrong types. In this case, array doesn't decay to pointer.
If you change the last line in the function to this :
return make_pair(&a[0],&b[0]);
it will compile, but it will still not work, as you are returning pointers to arrays, which are destroyed, once the function cpy() ends.
By the way, variable lenghts array are not standard c++.

You are trying to return pointer to a temporary value. As result the pointers will be point to a garbage.
Also you trying to cast string with decimal notation to integer.
You should return the pair of integers, which will be obtained by parsing the string at the numbers.
You can see the link below.
http://interactivepython.org/runestone/static/pythonds/BasicDS/ConvertingDecimalNumberstoBinaryNumbers.html

Related

String declaration initial length when not initialised

#include <iostream>
#include <cstring>
#include <cstdio>
using namespace std;
int main(){
char a[20];
cout<<strlen(a)<<endl;
return 0;
}
The output of this code is 11.
Why 11? When I have not initialised it.
As stated here: http://en.cppreference.com/w/cpp/string/byte/strlen,
The behavior (of strlen(str)) is undefined if there is no null character in the character array pointed to by str.
The issue you are facing is caused by uninitialized memory. With char a[20]; you are only reserving memory space, but you are not initializing it. Those 20 bytes can have any possible value and you have no guarantees that any of them is set to 0. That causes the unespected return value of the strlen() call, you simply were lucky that the function found a byte set to 0 before it could cause a crash.
To avoid any problem you should initialize your variables before using. For a null terminated sequence of char you can initialize like so:
char a[20] = "";
Or you can use std::string instead:
#include <iostream>
#include <string>
int main() {
std::string a;
std::cout << a.length() << std::endl;
return 0;
}
The output, if you are wondering, is 0.
If you find uninitialized array's length,The behavior is undefined. if you want correct result initialize it. or use this:
int a[20] = {};
or
memset(a,'\0',20) and then after check the length.

c++ strings vs vector<char> vs dynamic arrays

I was trying to use char* pointers to refer to strings and vector<char> & dynamic arrays & I have a doubt with the following results :-
CODE 1:-
#include <iostream>
#include <string>
using namespace std;
int main()
{
cout<<"executing...\n";
string s="abcde";
char *c=&s[0];
cout<<c<<"\n";
s.~string();
cout<<c<<"\n";
cout<<"executed";
return 0;
}
The output of this code is :-
executing...
abcde
abcde
executed
CODE 2:-
#include <iostream>
#include <vector>
using namespace std;
int main()
{
cout<<"executing...\n";
vector<char> v {'a','b','c','d','e'};
char *p=&v[0];
cout<<p<<"\n";
v.~vector();
cout<<p<<"\n";
cout<<"executed";
return 0;
}
The output for this code is :-
executing...
abcde
executed
CODE 3 (with dynamic arrays):-
#include <iostream>
using namespace std;
int main()
{
cout<<"executing...\n";
char* c=new char[20] {'a','b','c','d','e'};
char *p=c;
cout<<p;
delete[] c;
cout<<"\n"<<p<<"\n";
cout<<"executed";
return 0;
}
The output for this code is similar to CODE 2:-
executing...
abcde
executed
I want to know why CODE 1 produces an output different from CODE 2 & CODE 3 ? What problem does string have that it behaves differently from vector<char> & dynamic arrays ?
All the snippets of code access data that has been deleted, which has no defined behavior. Therefore, any further assumption is meaningless and left to the single case. Whether you're accessing a vector, char*, string there's no difference: it's always the same violation.
Well I guess this example is good enough to show that your objects of string & vector are deleted twice hence leading to undefined behaviour :-
#include <iostream>
using namespace std;
class X
{
int x;
public:
X()
{
cout<<"constructing\n";
}
// other member functions...
~X()
{
cout<<"destroying\n";
}
};
int main()
{
X object;
object.~X();
return 0;
}
Output will be :-
constructing
destroying
destroying
When behaviour is undefined there is no use of thinking about "WHY SUCH AN OUTPUT", etc stuffs !! Even I had a doubt regarding the reference counting of C++ strings but as many people are saying strings are no longer reference counted so CODE 1 is also producing undefined behaviour. However I liked you experimenting with codes. It's necessary to learn a language properly. Keep it up !!!

error: incompatible types in assignment of 'char*' to 'char [4000]'

I've been trying to solve an easy problem, but I can't figure why my program doesn't work. I want to concatenate a string.
Can you help me? If so, can you also explain me why it doesn't work?
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
ifstream in("sirul.in");
ofstream out("sirul.out");
char a[4000]="a",b[4000]="b",aux[4000];
int main()
{ int n,i;
in>>n;
if(n==1)out<<"a";
if(n==2)out<<"b";
for(i=3;i<=n;i++)
{
aux=strcpy(aux,b);
b=strcat(b,a);
a=strcpy(a,aux);
}
return 0;
}
strcpy and strcat work directly on the pointer you pass in as the first argument, then also return is so that you can chain calls. As such, assigning their result back to the destination pointer is redundant. In this case, it's also invalid, as you can't reassign an array.
The fix is to just not assign the return value of those calls:
strcpy(aux,b);
strcat(b,a);
strcpy(a,aux);
However, since you are using C++, you should use std::string instead, which gives you nice value semantics for your string data.
you can not do (see 2)
char b[4000]="b";
char aux[4000];
aux /* 2 */ = strcpy(aux /* 1 */ , b);
because aux is not a pointer, but array. you can pass it as pointer argument (see 1), but you can not "collect" the result "inside" aux (see 2).
As other suggested, just remove "collection" and it will work as you expect.
char b[4000]="b";
char aux[4000];
strcpy(aux /* 1 */ , b);
// or even:
const char *s = strcpy(aux /* 1 */ , b);
Also you are mixing C and C++ in one file.
Also probably there is possibility for buffer overflow.
#include <iostream>
#include <cstring>
#include <fstream>
using namespace std;
ifstream in("sirul.in");
ofstream out("sirul.out");
char a[4000]="a",b[4000]="b",aux[4000];
int main()
{
int n,i;
cin>>n;
if(n==1)cout<<"a";
if(n==2)cout<<"b";
for(i=3;i<=n;i++)
{
strcpy(aux,b);
strcat(b,a);
strcpy(a,aux);
}
return 0;
}
check out definition os strcpy, in should be cin and out should be cout

Returning arrays from a function in c++

I am trying to return an array from a function:
#include <iostream>
using namespace std;
int* uni(int *a,int *b)
{
int c[10];
int i=0;
while(a[i]!=-1)
{
c[i]=a[i];
i++;
}
for(;i<10;i++)
c[i]=b[i-5];
return c;
}
int main()
{
int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1};
int b[5]={1,3,4,3,0};
int *c=uni(a,b);
for(int i=0;i<10;i++)
cout<<c[i]<<" ";
cout<<"\n";
return 0;
}
I pass two arrays from my main() into my uni() function. There I create a new array c[10] which I return to my main().
In my uni() function I try to merge the non-negative numbers in the two arrays a and b.
But I get something like this as my output.
1 -1078199700 134514080 -1078199656 -1216637148 134519488 134519297 134519488 8 -1078199700
Whereas when I try to print the values of c[10] in the uni() function it prints the correct values. Why does this happen??
Is this something related to the stack?? Because I have tried searching about this error of mine, and I found a few places on stackoverflow, where it says that do not allocate on stack but I couldn't understand it.
Further it would become very easy if I allocate my array globally, but if this is the case then everything shall be declared globally?? Why are we even worried about passing pointers from functions?? (I have a chapter in my book for passing pointers)
Admittedly, the std::vector or std::array approach would be the way to go.
However, just to round things out (and if this is a school project, where the teacher gives you the obligatory "you can't use STL"), the other alternative that will avoid pointer usage is to wrap the array inside a struct and return the instance of the struct.
#include <iostream>
using namespace std;
struct myArray
{
int array[10];
};
myArray uni(int *a,int *b)
{
myArray c;
int i=0;
while(a[i]!=-1)
{
c.array[i]=a[i];
i++;
}
for(;i<10;i++)
c.array[i]=b[i-5];
return c;
}
int main()
{
int a[10]={1,3,3,8,4,-1,-1,-1,-1,-1};
int b[5]={1,3,4,3,0};
myArray c = uni(a,b);
for(int i=0;i<10;i++)
cout << c.array[i] << " ";
cout << "\n";
return 0;
}
Note that the struct is returned by value, and this return value is assigned in main.
You have the value semantics of returning an instance, plus the struct will get copied, including the array that is internal within it.
Live Example
You're returning a pointer to a local object. In the uni function, the variable c is allocated on the stack. At the end of that function, all of that memory is released and in your for loop you are getting undefined results.
As suggested in the comments, std::array or std::vector will give you copy constructors that will allow you to return the object by value as you're trying to do. Otherwise you'll have to resort to something like passing your output array in as an argument.
You are returning a pointer to an array that is being deallocated at the return statement. It's a dangling pointer. It's UB.
Use an std::vector or std::array and return by value. There are compiler optimizations that will avoid inefficiencies.

Pointers and recurency - I'm trying to save memory

I'm trying to write program that create squere for string. Squere has to be larger then string.length(). If there is word 'C++' I need 2x2 array to fill it inside.
So I have written code
#include <cmath>
#include <cstdlib>
#include <iostream>
#include <string>
using namespace std;
int pole(int &a,const int* l);
int main(){
string code;
cin >> code;
int wall=1;
pole(wall,code.length());
cout << wall;
system("PAUSE");
return 0;
}
int pole(int &a,const int* l){
if (a*a > l) return a;
else {
a+=1;
pole(a,l);
}
}
I bet that using pointer with recunrency save a lot of memory but I can't compile it. I'm trying to understand compilers error but is 2 hard for me ;/
Here is compiler list of errors
> in main()
11 25 Error] invalid initialization of non-const reference of type 'int&' from an rvalue of type 'int (*)(int&, const int*)'
6 5> [Error] in passing argument 1 of 'int pole(int&, const int*)'
in pole() 17 12
>[Error] ISO C++ forbids comparison between pointer and
> integer [-fpermissive]
Here:
pole(pole, code.length());
You are passing as the second variable the result of length(), which is of type std::string::size_type, which the function pole accepts a pointer to int. Those two types are incompatible.
The second problem is that one branch of your if statement inside pole does not contain a return statement, thus giving your program Undefined Behavior.
You may want to change your function pole this way:
int pole(int &a, std::string::size_type l) {
// ^^^^^^^^^^^^^^^^^^^^^^
// Also, passing by reference is unnecessary here
if (a*a > static_cast<int>(l)) return a;
// ^^^^^^^^^^^^^^^^
// Just to communicate that you are aware of the
// signed-to-unsigned comparison here
else {
a+=1;
return pole(a,l);
// ^^^^^^
// Do not forget this, or your program will have Undefined Behavior!
}
}
Here you can see your modified program compile and run.
You are trying to use an unsigned integer (coming from std::string::length) as a pointer in:
pole(wall,code.length());
Change your pole declarations to:
int pole(int a, int l);
Saving memory on int is just nonsense there. Pointers are sometimes even more memory expensive than simple integers.
You should learn to save memory with huge objects instead.
int pole(int &a,const int* l){
if (a*a > l) return a;
else {
a+=1;
pole(a,l);
}
}
first, you cannot initialize int* l with size_t argument.
Also you do later comparison between address, not value pointed too.
Is this what you wanted?