Why doesn't the address change as I increment str? I thought that when I performed pointer arithmetic, the pointer points to a different memory address. Therefore, shouldn't the memory address change as well?
#include <iostream>
using namespace std;
void reverse(char* str){
cout << &str << endl;
while(*str != '\0'){
cout << &str << endl;
str++;
}
}
int main(){
char str[] = "hello";
reverse(str);
}
&str is the address of the pointer. You are changing the pointer as you iterate over the characters, but the pointer that you are changing is still located at the same spot.
Edit: change your cout << &str << endl; to cout << "pointer loc<" << &str << "> pointer value<" << (void*)str << ">" << endl; and see what it says.
Related
Take this question when i read a program (quote:c++ primer plus) 4.22 and make some change in it
#include <iostream>
#include <cstring>
using namespace std;
char * getName();
int main(int argc, const char * argv[]) {
// insert code here...
char *name;
name = getName();
string sb = name;
cout << name << " at " << (int *)name << "\n";
cout << *name << " " << sb << endl;
cout << &sb << endl;
delete [] name;
name = getName();
sb = name;
cout << name << " at " << (int *) name << "\n";
cout << *name << " " << sb << endl;
cout << &sb << endl;
delete [] name;
cout << sb << endl;
cout << &sb << endl;
return 0;
}
char *getName()
{
char temp[80];
cout << "Enter last name: ";
cin >> temp;
char *pn = new char[strlen(temp) + 1];
strcpy(pn, temp);
return pn;
}
and there have no memory leak.
i check sb's address is different from name.
i think may it work like this
std::string
first step : malloc (char *, sizeof(char *) * sizeof(name) )
then : snprintf( string , sizeof (string) , "%s", name)
final : string get a new address
if i use a statement:
string = string + " am i a pointer";
it still work.
i guess it is really a pointer!
just realloc it
hereby, i think string is kind of char* or char array, i try to *string then the compiler tell me something wrong with it! i can't use like this, so i hope someone can explain what type of string is in compiler and how it work! why string is not a pointer? or it's actually a pointer but it have special method to use?
tip:All work on mac os
i hope someone can explain what type of string is
It is a class.
why string is not a pointer? or it's actually a pointer but it have special method to use?
It's not a pointer. A pointer couldn't store the necessary data to fulfill the requirements defined by the standard.
i think string is kind of char* or char array
It's not. However, it quite probably does have a char pointer to an array as a data member.
I'm bit puzzled by how modifying a std::string beyond its size is handled? In an example I tried, it allowed me to modify the string beyond its size using op[] (and I'm aware that standard doesn't stop you from doing it). However, when I print the string using cout it prints the original string but when I print whats returned by cstr (), it prints the modified version. How does it keep track of both sizes (3 & 5)?.
#include <string>
#include <iostream>
using namespace std;
int main(void) {
std::string a = "abc";
cout << "str before : " << a << endl;
const char * charPtr = a.c_str ();
cout << "c_str before : " << charPtr << endl;
cout << "str size / capacity : " << a.size () << ", " << a.capacity () << endl;
a[3] = 'd';
a[4] = 'e';
cout << "str after : " << a << endl;
const char * charPtr2 = a.c_str ();
cout << "c_str after : " << charPtr2 << endl;
cout << "str size / capacity : " << a.size () << ", " << a.capacity () << endl;
return 0;
}
output :
str before : abc
c_str before : abc
str size / capacity : 3, 3
str after : abc
c_str after : abcde
str size / capacity : 3, 3
Although you already got a correct comment saying the behaviour is undefined, there is something worthy of an actual answer too.
A C++ string object can contain any sequence of characters you like. A C-style string is terminated by the first '\0'. Consequently, a C++ string object must store the size somewhere other than by searching for the '\0': it may contain embedded '\0' characters.
#include <string>
#include <iostream>
int main() {
std::string s = "abc";
s += '\0';
s += "def";
std::cout << s << std::endl;
std::cout << s.c_str() << std::endl;
}
Running this, and piping the output through cat -v to make control characters visible, I see:
abc^#def
abc
This explains what you're seeing: you're overwriting the '\0' terminator, but you're not overwriting the size, which is stored separately.
As pointed out by kec, you might have seen garbage except you were lucky enough to have an additional zero byte after your extra characters.
I wrote a simple program to see how C++ handles pointers to string objects (new to OOP), and I was suprised to see that string* as which was assigned the memory address of string a, didn't store a value equivalent to &a. Also, the console didn't print the value to *as. Could this be an error on my end or the system, or am missing something fundamental here?
#include <iostream>
#include <string>
using std::cout;
using std::cin;
using std::endl;
using std::string;
string a = "asdf";
string* as = &a;
string* as_holder = &a;
int main()
{
cout << "a = " << a << "\t" << "&a = " << &a << " *as = " << *as << endl
<< "as = " << as << endl
<< "++as = " << ++as << endl
<< "*as = " << *as << endl << endl;
return 0;
}
output:
a = asdf &a = 011ff68C *as =
as = 011FF6A8
++as = 011FF6A8
*as =
In my test of the valid portion of your program (the first two lines of cout), the printout showed the same address:
a = asdf &a = 0x8049c90 *as = asdf
as = 0x8049c90
(link to a demo)
Lines three and four, however, amount to undefined behavior: once you do ++as, you are moving the pointer to the next std::string in an "array of strings" (which does not exist). Therefore, the subsequent attempt at dereferencing as is undefined behavior.
If you would like to obtain a pointer to the data of your string, such that you could move to the next character by incrementing the pointer, you could use c_str() member function, like this:
const char *as = a.c_str();
as++;
cout << as << endl; // This would print "sdf"
Why does this not work:
SomeClass::SomeClass(char *lit) //Ctor
{
str = new char[strlen(lit)+1]; // str is a pointer to char in SomeClass
strcpy(str,"have");
cout << str << " " << "In Ctor" << " +Size=" << strlen(str)<< endl;
}
The above code shows a string with length 0. But this code works:
SomeClass::SomeClass(char *lit)
{
char newstr[strlen(lit)+1];
strcpy(newstr,"have");
cout << newstr << " " << "In Ctor" << " +Size=" << strlen(newstr)<< endl;
}
Here is the complete code.
EDIT:
Added the link to Ideone which OP removed after I answered the Question.
Without the link to source code, this Q & answer to it is useless.
There is no problem with the strcpy, You are just messing your pointer.
The problem is here:
str = new char[strlen(lit)+1];
strcpy(str,lit);
length=leng(); <------------- str points to \0 after this call
cout << str << " " << "In Ctor" << " +Size=" << strlen(lit)<< endl;
str is your class member and You move the pointer str to point to the \0 in the function leng(), Naturally, You don't see any output in the next statement.
Solution is to hold the starting address in a separate pointer inside the function.
int String :: leng()
{
int length=0;
char *tempPtr= str; <----------- Store the address in a temporary pointer
while(*str)
{
length++;
str++;
}
str = tempPtr; <---------- Point the Pointer member to right address again
return length;
}
Another way to write String::leng():
int String::leng()
{
char *endPtr = str;
while(*endPtr)
endPtr++;
return endPtr - str;
}
I have a structure and i am trying to print the address of their member variables.
When tried to print the address of char member variable through &(f.c) i am not getting their address.
Here is the code:
struct foo
{
char c;
short s;
void *p;
int i;
};
int main()
{
cout << "Size of foo: " << sizeof(foo) << endl;
foo f;
cout << "Address of c: " << reinterpret_cast<void*>(&f.c) << endl;
cout << "Address of c: " << &(f.c) << endl;
cout << "Address of s: " << reinterpret_cast<void*>(&f.s) << endl;
cout << "Address of s: " << &(f.s) << endl;
cout << "Address of p: " << reinterpret_cast<void*>(&f.p) << endl;
cout << "Address of p: " << &(f.p) << endl;
cout << "Address of i: " << reinterpret_cast<void*>(&f.i) << endl;
cout << "Address of i: " << &(f.i) << endl;
return 1;
}
Output
/pp/cplus/bas ]$ ./a.out
Size of foo: 12
Address of c: 0xffbfe680
Address of c: //----------- &(f.c). Why this is empty..
Address of s: 0xffbfe682
Address of s: 0xffbfe682
Address of p: 0xffbfe684
Address of p: 0xffbfe684
Address of i: 0xffbfe688
Address of i: 0xffbfe688
just want to know why it is not printing when i tried accessing it through &(f.c)
Compiled using gcc version 3.4.6
cout has an operator<< overload for char* which treats the argument like a pointer to a C-string and it tries to print all the characters in that C-string until it gets to a NUL (0) byte. To get around this behaviour, you have to cast the addresses to void* like you are doing every other line.
You have just experienced the reason that arrays are sometimes considered second-class data types because they are treated specially in some situations (i.e. arrays of char are treated differently by some things but not others).
The Address of c: is empty because that's what you get when you try to print a string pointed to by &f.c. As dark_charlie pointed out, using an uninitialised variable is undefined behaviour, so technically anything can happen, but the former is probably the explanation for what you're seeing (though we can only guess).
The reason is that without the reinterpret cast &(f.c) is a char* pointer which is treated as a string by cout. Because you haven't filled the char with anything, you invoke an undefined behavior (i.e. it can print anything).