473,788 Members | 2,924 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Doubt regarding returning const char*

Hi,
Please refer program below:

#include <string>
#include <cstdio>
using namespace std;
const char* f();

main()
{
const char* str = f();
printf("%s", const_cast<char *> (str));
}
Now I have 2 implementations for f():

1.
const char* f()
{
return "Hello";
}

2.
const char* f()
{
string str = "Hello";
return str.c_str();
}
Are both of these implemetations exactly equivalent and "Safe" with
respect to memory model?
[
e.g.
char* f1()
{
char a[10];
return a;
}
is not safe.
]

What happens when we return a const char*?

Thanks & Regards,
- Kiran Agashe

Feb 3 '06 #1
9 10167
GB
ki**********@gm ail.com wrote:
Hi,
Please refer program below:

#include <string>
#include <cstdio>
using namespace std;
const char* f();

main()

int main()
{
const char* str = f();
printf("%s", const_cast<char *> (str));
}
Now I have 2 implementations for f():

1.
const char* f()
{
return "Hello";
}
This is okay.

2.
const char* f()
{
string str = "Hello";
return str.c_str();
}


This is not okay. The str object will be destroyed when it goes out of
scope, which happens when f returns. Since the object str will no longer
exist, the pointer returned by std::string::c_ str will no longer be valid.

Gregg
Feb 3 '06 #2

ki**********@gm ail.com wrote:
Hi,
Please refer program below:

#include <string>
#include <cstdio>
using namespace std;
const char* f();

main()
{
const char* str = f();
printf("%s", const_cast<char *> (str));
}

main() should be int main().
const_cast<>() is not needed here.

Now I have 2 implementations for f():

1.
const char* f()
{
return "Hello";
}

This one returns a const char pointer to string a "Hello" which
probably
was stored in a read only segment of the program which is good.
2.
const char* f()
{
string str = "Hello";
return str.c_str();
}

This is not safe.

writing string str = "Hello"; might leave you with an impression that
it is basically
the same as in the previous implementation of f() but this actually is
interpreted
as if you had typed string str("Hello"); which creates a local string
object and
copies "Hello" internally.

Thus when the the function returns the local string object is
destructed and the
pointer to it's internal copy of "Hello" is no longer valid.

Are both of these implemetations exactly equivalent and "Safe" with
respect to memory model?

Neither equivalent nor safe.
What happens when we return a const char*?


In general it means that a pointer to constant character is returned,
that is
the character const points to cannot be changed.
P.Krumins

Feb 3 '06 #3
ki**********@gm ail.com wrote:
Hi,
Please refer program below:

#include <string>
#include <cstdio>
using namespace std;
const char* f();

main()
{
const char* str = f();
printf("%s", const_cast<char *> (str));
Why the const_cast?
}
Now I have 2 implementations for f():

1.
const char* f()
{
return "Hello";
}
Should be OK as you are returning a literal, not sure if it is
guaranteed to be safe.
2.
const char* f()
{
string str = "Hello";
return str.c_str();
}
Assuming you mean std::string, unsafe because str is a temporary. I
will probably work in your trivial case, but not safe.

Are both of these implemetations exactly equivalent and "Safe" with
respect to memory model?

No, one uses a string literal, one a temporary variable.

All the const is doing is preventing you from modifying the data pointed
to by the returned pointer.

--
Ian Collins.
Feb 3 '06 #4
Hi again,

I tried to check the assembler code for both implemetations of f().
1.
const char* f()
{
return "Hello";
}

2.
const char* f()
{
string str = "Hello";
return str.c_str();
}
In both cases there is an entry:

..asciz "Hello"

in the assembler files generated.

Does this mean that even in the second case a string literal "Hello" is
present for the entire lifetime of the program?

I agree that std::string str is temporary.

But instead of temporary variable, str.c_str() may be refering to the
string literaral stored in the read only segment of the program!

I don't understand assemble code fully.
Please correct me if I am wrong :-)

Regards,
- Kiran

Feb 3 '06 #5
GB
ki**********@gm ail.com wrote:
Hi again,

I tried to check the assembler code for both implemetations of f().
1.
const char* f()
{
return "Hello";
}

2.
const char* f()
{
string str = "Hello";
return str.c_str();
}
In both cases there is an entry:

.asciz "Hello"

in the assembler files generated.

Does this mean that even in the second case a string literal "Hello" is
present for the entire lifetime of the program?

I agree that std::string str is temporary.

But instead of temporary variable, str.c_str() may be refering to the
string literaral stored in the read only segment of the program!


It's possible that the std::string object is optimized out of this
trivial program, but there is no guarantee, and it is not safe to assume
that this will work in general.

The .asciz entry exists in the second case because there is still a
string literal in your program that has to come from somewhere at
runtime. But if you look at the assembly code, you will probably see
that the string object allocates its own memory and then copies the
..asciz location into its own memory so it has a copy of it. This is what
the c_str function is likely to be returning, and this will probably get
deallocated before f returns.

Gregg
Feb 3 '06 #6
Does this mean that:

const char* f()
{
const char* s = "Hello";
return s;
}

is not also safe???

Thanks & Regards,
- Kiran Agashe

Feb 3 '06 #7
ki**********@gm ail.com wrote:
Does this mean that:
Does what? Please quote!
const char* f()
{
const char* s = "Hello";
return s;
}

is not also safe???

No, it is safe, you are still returning a pointer to the literal. With
a string, you are returning a pointer to a _copy_ of the literal.

--
Ian Collins.
Feb 3 '06 #8

<ki**********@g mail.com> wrote in message
news:11******** *************@g 43g2000cwa.goog legroups.com...
Hi again,

I tried to check the assembler code for both implemetations of f().
1.
const char* f()
{
return "Hello";
}

2.
const char* f()
{
string str = "Hello";
return str.c_str();
}
In both cases there is an entry:

.asciz "Hello"

in the assembler files generated.

Does this mean that even in the second case a string literal "Hello" is
present for the entire lifetime of the program?

I agree that std::string str is temporary.

But instead of temporary variable, str.c_str() may be refering to the
string literaral stored in the read only segment of the program!

I don't understand assemble code fully.
Please correct me if I am wrong :-)

Regards,
- Kiran


There is a constant string literal, but it's only used to initialize the
string, which stores it's data in dynamic memory.

This is pseudo code, and not exactly the way it's done, but something like
this happens.

std::string str = "Hello";

Okay, first the constructor is called then assignment. The std::string
contains a pointer to the data of where the chars are stored. The
constructor calls new for (most likely in this case) 0 bytes. Then the
assignment says to make it equal to = "Hello"; and the std::string releases
it's allocated memory, then calls new for 5 byte (enough to store 'H' 'e'
'l' 'l' 'o'). It then copies character by character into the dynamically
allocated array (it might copy all 5 chars at once, but same differnce).

Now, to further complicate things, .c_str() doesn't even point to this
memory, because std::string is not null terminated like c-style strings. I
believe when you call c_str() that std::string returns a pointer to
temporary memory (not positive on that, it may be permanent until the
std::string changes). But it points to memory that is now null-terminated,
which means it most likely copies it *again* and gives you a pointer to
that.

You are far removed from the
..asciz "Hello"
storage by a few copies. At least 1. Probably 2.

Easy way to figure that out.

const char[] Hello = "Hello";
std::string str = Hello;

Now, print out the addresses of Hello and str.c_str(). you'll see they're
different.
Feb 3 '06 #9

Jim Langston wrote:

<snip>
This is pseudo code, and not exactly the way it's done, but something like
this happens.

std::string str = "Hello";

Okay, first the constructor is called then assignment. The std::string
contains a pointer to the data of where the chars are stored. The
constructor calls new for (most likely in this case) 0 bytes. Then the
assignment says to make it equal to = "Hello"; and the std::string releases
it's allocated memory, then calls new for 5 byte (enough to store 'H' 'e'
'l' 'l' 'o'). It then copies character by character into the dynamically
allocated array (it might copy all 5 chars at once, but same differnce).
This is a common misconception. Despite the use of the = sign, there is
no assignment going on here. An unnamed temporary string is constructed
using the constructor that takes a const char*. Then str is initialised
from that unnamed temporary using the std::string *copy constructor*.
In fact, the compiler is allowed to elide the use of the temporary and
construct str directly using the constructor taking a const char*.

None of this affects your explanation of what the OP was seeing, but
this misconception seems to be a cause of confusion between
initialisation and assignment, so I thought it worth mentioning.
Now, to further complicate things, .c_str() doesn't even point to this
memory, because std::string is not null terminated like c-style strings. I
believe when you call c_str() that std::string returns a pointer to
temporary memory (not positive on that, it may be permanent until the
std::string changes).


Yep. The pointer returned by c_str() is valid until you call a
non-const member function for the string (or in the OP's case, the
string is detroyed).

<snip>

Gavin Deane

Feb 3 '06 #10

This thread has been closed and replies have been disabled. Please start a new discussion.

Similar topics

1
1705
by: SK | last post by:
Hi all, I have a doubt in C++ Templates by Nicolai M. Josuttis. On Page 17 there is a line "In general, it is a good idea not to change more than necessary when overloading function templates. You should limit your changes to the number of parameters or to specifying template parameters explicitly." Can anyone explain the meaning of these lines to me?
18
2145
by: cppaddict | last post by:
Hi, Is it considered bad form to have the subscript operator return a const reference variable? If not, what is the proper way to do it? My question was prompted by the code below, my problematic attempt to implement a subscript operator that returns a const reference. The dubious code is marked at the end. <code>
4
1821
by: Siemel Naran | last post by:
Hi. I have found one advantage of returning values through the argument list. It's that we have to store the return value. But when we return by value, we may forgot to store the return value. Consider, void f(int x, int& i); int i, j; f(1, i);
8
1782
by: junky_fellow | last post by:
what would be the output for the following piece of code ? if ( "hello" == "hello" ) printf("True\n"); else printf("False\n"); What is the reason for that ?
17
2334
by: Ashwin | last post by:
hi guys, i have overloaded the << operator.as shown below. ostream& operator<<(ostream &out, const student &a) { out<<a.idno; out<< " " ; // out<< a.name; out<< " " ; // out<< a.marks << endl;
8
2402
by: toton | last post by:
HI, One more small doubt from today's mail. I have certain function which returns a pointer (sometimes a const pointer from a const member function). And certain member function needs reference (or better a const reference). for eg, const PointRange* points = cc.points(ptAligned);
42
6827
by: mellyshum123 | last post by:
I need to read in a comma separated file, and for this I was going to use fgets. I was reading about it at http://www.cplusplus.com/ref/ and I noticed that the document said: "Reads characters from stream and stores them in string until (num -1) characters have been read or a newline or EOF character is reached, whichever comes first." My question is that if it stops at a new line character (LF?) then how does one read a file with...
8
2053
by: somenath | last post by:
Hi All, I have a doubt regarding the pointer assignment . Please have a look at the following program . #include<stdio.h> #include<stdlib.h> #define NAMESIZE 10 #define SAFE_FREE(t) if(t)\ {\
1
2113
by: sunil | last post by:
Hi, Am writing one C program for one of my module and facing one problem with the regular expression functions provided by the library libgen.h in solaris. In this library we are having two functions to deal with the regular expressions char *regcmp(const char *string1, /* char *string2 */ ,
0
10364
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10172
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
10110
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9967
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
8993
agi2029
by: agi2029 | last post by:
Let's talk about the concept of autonomous AI software engineers and no-code agents. These AIs are designed to manage the entire lifecycle of a software development project—planning, coding, testing, and deployment—without human intervention. Imagine an AI that can take a project description, break it down, write the code, debug it, and then launch it, all on its own.... Now, this would greatly impact the work of software developers. The idea...
0
6750
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5398
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
1
4069
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system
3
2894
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.