#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.
Related
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 !!!
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
I have a question related to dynamic memory. I have pretty much given up on using it and use vectors instead now, but would still love to know why the following type of code often gives me a runtime error with bad memory allocation. Is there a way to do this with dynamic memory?
The idea is basically using a loop to increase the size of an array, based on some condition. As stated, I now only use vector.push_back() for this, but thought I'd post and see if there were any insights.
#include <string>
#include <iostream>
#include <fstream>
#include <sstream>
#include <new>
int main()
{
ifstream infile.open("file.txt");
string str1, str2; stringstream os;
int length;
string *vecarr = new string[length];
length = 0;
while(!infile.eof())
{
getline(infile,str1);
if(str1.find("expression") != string::npos)
{
length++;
vecarr[length-1] = str1;
}
}
infile.close();
return 0;
}
length is uninitialized in the expression new string[length], so this is plain undefined behaviour. You must not read an uninitialized int variable.
trying to get ‘sval’ to contain the string “$1” – “$500” for array indexes 0-499. in the following code, however itoa is giving me strange strings in the code below:
#include<iostream>
#include <stdio.h>
#include <stdlib.h>
using namespace std;
typedef struct data_t {
int ival;
char *sval;
} data_t;
void f1(data_t **d);
int main()
{
data_t *d;
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
f1(&d);
}
/* code for function f1 to fill in array begins */
void f1(data_t **d)
{
int i;
char str[5];
for (int i=0; i<500; i++)
{
(*d)[i].ival=i+1;
itoa (i,str,10);
(*d)[i].sval= str;
}
}
it also seems itoa has been depreciated, but that was what i got when i googled int to string
You don't need ltoa, cout should be just fine. Why do you need to keep the number and its string representation in the array? when you do cout << 10 you get "10" on the output, you don't need any conversions of your own
You, on the other hand, do ltoa without allocating any memory for the strings, which is not healthy as you have probably noticed. You use a local variable (the same, for all the 500 array members), which you try to access after you exit the function - a big no-no, its undefined behavior.
And:
d=static_cast<data_t*>(malloc(500)); //is this even needed?
d = new data_t[500];
No. Not only not needed - shouldn't be there at all! When in C++ - use new and delete, never malloc, that's a C function.
Hello
Can somebody explain why second cout in func(char *p) doesn't work:
#include <cstdlib>
#include <iostream>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
using namespace std;
char *strhex(char *str);
char *func(char *p);
int main()
{
char *ptr;
char *p=strhex("d");
cout<<"main:"<<p<<endl;
cout<<func(p)<<endl;
system("PAUSE");
return 0;
}
char *func(char *p)
{
cout<<"func1:"<<p<<endl;
char buffer[500]="";
char *zbuffer = buffer;
cout<<"func2:"<<p<<endl; ///doesn't work
return zbuffer;
}
char *strhex(char *str)
{
char buffer[500]="";
char *pbuffer = buffer;
int len = strlen( str );
for( int i = 0; i < len ;i++ )
{
itoa(str[i],pbuffer,16);
pbuffer +=2;
};
*pbuffer = '\0';
pbuffer=buffer;
return pbuffer;
}
Edit:
i'm using DEV C++ 4.9.9.2 on Windows
One big problem here is that strhex is returning a pointer to a local variable (buffer[]). This variable goes out of scope at the end of the function, so the return value points at undefined memory contents that can be overwritten at any time.
Your entire code doesn't work. Both functions return pointers to local arrays, which don't point to anything valid after the function returns. That causes undefined behavior. Since the value of p is one of these invalid pointers, you can't depend on it to be anything at any particular time — that memory probably gets overwritten during func(). You need to either new[] and delete[] the appropriate memory or, preferably, use a proper C++ data structure like std::string.
it looks like it is working but the second cout in main is not printing out a value because you are returning an empty buffer.
Adding to others answers:
You need not reset pbuffer to point to the start of the array and then return it's value:
pbuffer=buffer;
return pbuffer;
you can just say
return buffer;
the array name is also a pointer(pointer to the first element of the array.