Pointer increment answer not understood - c++

I have been trying for such code
#include <iostream>
using namespace std;
int main()
{
int t=1;
cout<<t<<" ";
int *b = new int(t);
cout<<*b++<<" ";
cout <<*b<<" ";
cout<<t<<" ";
return 0;
}
It is giving me output as 1 1 0 1. I cant understand 0 in the output. Please explain me why this is happening ?

The precedence of the ++ operator is higher than that of the * operator in this case. You are thus incrementing the pointer b itself rather than the memory being pointed to (which is presumably your intention).
To get the behaviour you want:
cout<<(*b)++<<" ";

After the line
cout << *b++ << " ";
b points to memory beyond what was allocated.
The line after that,
cout << *b << " ";
dereferences memory beyond valid limits. Hence, it is cause for undefined behavior.

Related

Entering value to dynamically allocated memory at runtime

Following is the code I wrote for reading a value at run time to dynamically allocated memory:
void main()
{
clrscr();
int *p = new int[5];
int *a = new int();
cin >> *a; // **line 5**
cout << *a << "\n"; // **line 6**
cout << &p; // line 7
cout << *p; // line 8
cout << "\nEnter 5 no for array\n";
for (int i = 0; i <= 4; i++)
{
cout << &p[i] << " :- ";
cin >> p[i]; // LINE 12
}
for (i = 0; i <= 4; i++)
cout << "\n" << p[i]; // LINE 16
delete[] p;
delete a;
getch();
}
I would like to know that while entering data for user in integer, we have to use *a with cin and cout for entering data in line 5 & 6 but in case of array we just gave the pointer variable name in line 12 & 16. Can anyone please tell me why we are having this difference?
Moreover can anyone also please tell me the difference between output of line 7 & 8.
You don't "have to"; you could have written cin >> a[0].
For built-in types and pointers and such, a[b] is *(a+b) is *(b+a) is b[a] and you can interchange them all.
It's only convention that leads to a choice. Like generally if you'd allocated more than one int you'd use "array notation" (a[i]) and if you'd allocated only one int you'd use a straight-up dereference (*(a+0), or *a).
But the language doesn't really care how many elements you allocated because either way you just have a pointer to "one or more" consecutive elements.
tl;dr this is just how the syntax was designed.
As for your second question, &p and *p give different results because they mean different things, and I'll leave discerning that difference as an exercise to the reader.

c++ dynamic allocation of char *

I have a problem in the following piece of code, the problem simply is that values of the dynamically-allocated array of char* changes from line number 24 to line number 28 and I can't figure out why
Code:
#include <iostream>
#include <string>
#include <stdlib.h>
#include <ctype.h>
#include <cstring>
using namespace std;
int main() {
string x = "5+90-88n";
unsigned int i =0, k=0, argc=0;
char** argv = new char*[x.length()];
while (i < x.length()) {
if (isdigit(x[i])) {
k=0;
while (isdigit(x[i+k])) {k++;}
argv[argc] = (char*)x.substr(i,k).c_str();
i+=k;
} else {
argv[argc] = (char*)x.substr(i,1).c_str();
i++;
}
cout << argc <<" "<< argv[argc] <<endl;
argc++;
}
cout << " ------ \n";
for (unsigned int kk =0; kk<argc; kk++) {
cout << kk << " " << argv[kk] << endl;
}
return 0;
}
Output :
0 5
1 +
2 90
3 -
4 88
5 n
------
0 n
1 n
2 n
3 n
4 n
5 n
I was expecting the upper and lower parts to be the same, being not the same means that even there is some mistake I did and didn't notice or there is something I don't know about using dynamic allocation.
The array pointed to by the pointer returned std::string::c_str is owned by the string. substr returns a temporary string object that goes out of scope at the end of the expression in which substr was called.
Taken together these two facts mean that the arrays pointed to by the pointers in argv get deleted immediately after you create them. By the time you get around to printing any of them they are long dead.
It seems a simple problem, but it doesn't actually, It took me hours to try to find the answer.
Let us see this code below:
int main()
{
const char* p;
const char* p1;
{
string x = "xt";
p = x.substr(0, 1).c_str();
cout << p << endl;
p1 = x.substr(1, 1).c_str();
cout << p1 << endl;
}
cout << p << endl;
cout << p1 << endl;
return 0;
}
Its output is:
x
t
t
t
When running in the {} scope, p and p1 are pointing to temporary variables, and now these variables are existing, so we can print p an p1 out. When the code running out of the {} scope, those temporary variable are inexistent, we just cannot refer to them again, but their memory and data are still existent. So we still can print the value of p and p1 out without a memory crash.
But why the value of p and p1 are the same?
Let us see this:
int main()
{
const char* p;
const char* p1;
{
string x = "xt";
string t1 = x.substr(0, 1);
p = t1.c_str();
cout << p << endl;
string t2 = x.substr(1, 1);
p1 = t2.c_str();
cout << p1 << endl;
}
cout << p << endl;
cout << p1 << endl;
return 0;
}
Its output is:
x
t
x
t
just as you expected.
Maybe there is something strange with substr. But I am not sure about it. I'll go on checking.
And, as the code shows above, p and p1 are pointing to different temporary variables, according to the different outputs, p and p1 may be pointing to the same temporary variable in the first example.
Let us back to your code, char** is pointers to pointers, It is wrong to frequently make a pointer point to a temporary variable.
My suggestion is that you might use a array of string instead of a array of pointer.
Hope that helps.
You are not allocating anything for the temporary sub-string string object created which creates a temporary pointer to an array.
Doing something like this should work but won't recommend as you can't free that memory anymore:
argv[argc] =(char*)((new string(x.substr(i,k)))->c_str());
You need the string object to survive as c_str returns a constant pointer to the string object's value. If string object doesn't exist, what will be that pointer pointing to? Read this: c_str cplusplus.com
It is recommended to store the sub-strings to some array/vector, and then do necessary work with pointers.
#Mohamed Ibrahim, I think I have gotten the real reason of this problem that the two output are different.
Let us consider one problem at first:
What is happening when a temporary variable has ended its lifetime?
Please see this code:
int a1 = 9;
int& a = a1;
{
int b = 10;
a = b;
cout << a << endl;
int c = 11;
count << a << endl;
}
cout << a << endl;
its output is:
10
11
11
But as we know, 'b' and 'c' has gone when we try to print 'a' out at the last time. Why does 'a' still hold a value?
The reason is the memory and data of 'b' and 'c' is still existing in spite of 'b' and 'c' have gone. 'a' is a reference, it refered to the memory of 'b' and 'c'.
Let us continue considering:
When will the memory and data of a temporary variable be swept?
Even a temporary lifetime has been ended, but its memory and data are still existing until another temporary variable is declared, and the value of the new varialbe covers the value the old variable in that memory, and then all of the pointers and the references who are refering to the old variable, their value has been changed, we can print their value out to prove.
So, in your code, a new temporary variable of string will be declared in each loop, despite you can print a correct value out, but the new variable has covered the old. After the while scope ended, only one variable's value is existing, it is the last variable you declared, all of the others have been covered. So, we just could see the same value in the last output.
The way to remain every value is to save it in a global variable:
int main()
{
string x = "5+90-88n";
unsigned int i =0,k=0,argc=0;
char** argv = new char*[x.length()];
while ( i< x.length())
{
if (isdigit(x[i])) { k=0;
while(isdigit(x[i+k])) {k++;}
char* temp = (char*)x.substr(i,k).c_str();
argv[argc] = new char[strlen(temp) + 1];
memset(argv[argc], 0, sizeof(argv[argc]));
strcpy(argv[argc], temp);
i+=k;
}
else {
char* temp = (char*)x.substr(i,1).c_str();
argv[argc] = new char[strlen(temp) + 1];
memset(argv[argc], 0, sizeof(argv[argc]));
strcpy(argv[argc], temp);
i++;
}
cout << argc <<" "<< argv[argc] <<endl;
argc++;
}
cout<<" ------ \n";
for( unsigned int kk =0;kk<argc;kk++) { cout <<kk <<" "<<argv[kk]<<endl; }
return 0;
}
the above code could work well, but it is unsafe, I don't like this way of coding.
My suggestion, as I have ever said, don't try to make a pointer point to a temporary variable, never do that. No offence, please correct your code.

For loop condition is a variable without comparison

int a[5] = {1,2,3,4,5};
for (int i = 0; a[i]; i++)
{
cout << i;
}
This code produces the output of "0 1 2 3 4".
What does it compare a[i] against, and how does it know to stop at the end of the array and not go over?
You code causes undefined behaviour. The expression a[i] will evaluate as true if non-zero and as false if zero. When you run it, you're getting lucky that there is a 0 word immediately following your array in memory, so the loop stops.
It's reading past the array and the memory there just happens to be zero, by sheer luck. Reading past the end of that array is undefined behavior and the outcome might change at any time, so never rely on it.
You can think of a[i] as being compared to 0, it simply fetches the number retrieved from the location in memory and if 0 is the value that lives at that memory, then the loop exits, if it is any other number the loop continues.
Suppose an int is 4 bytes on the system. a is given an address, lets pretend it is 0xFF00 when we try to evaluate a[0] we retrieve the data value stored at memory 0xFF00. a[1] would retrieve data from memory 0xFF04, etc. Your program only assigns values to the first 5 memory locations, so when we retrieve the data at beyond these locations they could be anything from 0 to INT_MAX. If it happens to be 0 then the loop exits, however if it happens to be something else the loop continues.
Your could adjust your program like so to see it better:
#include <iostream>
using namespace std;
int main() {
int a[5] = {1,2,3,4,5};
int i;
for (i = 0; a[i]; i++)
{
cout << "At memory address: " << &a[i]
<< " lives the value: " << a[i] << endl;
}
cout << "At memory address: " << &a[i]
<< " lives the value: " << a[i]
<< ", and this is why the loop ended." << endl;
return 0;
}

Strcmp does not behave as expected, Returns 0 when comparing two unequal strings

I am having understanding a weird behavior of strcmp function, which will be illustrated by the following code:
#include <iostream>
#include <cstring>
using namespace std;
int main()
{
char *p = "no";
cout << p << endl; //Output: no
cout << &p << endl; //Output: 0x28ac64
cout << strlen(p) << endl; //Output: 2
cout << strcmp(p, "no") << endl; //Output: 0
cin >> p; //Input: bo
cout << p << endl; //Output: bo
cout << &p << endl; //Output: 0x28ac64
cout << strlen(p) << endl; //Output: 2
cout << strcmp(p, "no") << endl; //Output: 0
return 0;
}
What I fail to understand is why the output of line 15 is 0. 0 means the two strings are equal, which is clearly not the case. What am I missing here?
P.S. I do apologize for the escape characters in the headers, but I could not get iostream to display if I removed it. Though I am posting this, I will figure out how to get it right for next time. :)
The problem is that p points to a string literal, therefore your attempt to modify the string literal with cin >> p; leads directly to undefined behavior.
What's most likely happening is that the compiler is treating the string literal as constant (since you're not supposed to modify it) and therefore, (at compile time) determining what the result from strcmp should be, and producing that. The fact that you're modifying it at run-time is ignored, because you're not supposed to do that anyway.
Unfortunately for compatibility many compilers support this:
char *p = "no";
Which should fail to compile and correct one is:
const char *p = "no";
If you fix that (and you should get at least warning), you would see what is the issue with following compile errors.
p is pointing to the first element of an array of const char. Attempting to modify these values (as you do in cin >> p) invokes undefined behaviour.

I'm missing something simple here (run-time execution precedence?)

Execution of this simple code:
int foo(int* a){
cout <<"a="<<a;
*a=1;
cout <<", *a="<<*a<<endl;
return 0;}
int main () {
int* ptr;
ptr=new int[2];
ptr[0]=0;
ptr[1]=0;
cout<< foo(ptr) <<" "<< ptr <<" *ptr="<< *ptr <<endl;
cout<< foo(ptr) <<" "<< ptr <<" *ptr="<< *ptr <<endl;
return 0;}
Leads to (linux):
a=0x939f008, *a=1
0 0x939f008 *ptr=0
a=0x939f008, *a=1
0 0x939f008 *ptr=1
Please explain why *ptr=0 in the second line, but not in the fourth; could it be, that "things" are "fetched" to cout from right to left? Than - how does it really work (step-by-step at runtime)?
The order of evaluation of arguments to a function is Unspecified as per the C++ Standard.
It may be:
Left to Right or
Right to Left or
Any other order
One of my previous answer here, explains this in depth and detail.