473,326 Members | 1,972 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,326 software developers and data experts.

string

Hi,

Is it safe to have a pointer to a string.c_str() created locally inside
a function? For example, would the following code give me headace if a
try to use "c" after calling foo() ?

const char *c;

void foo ()
{
string str = "Hello";
c = str.c_str();
}

Thanks,
Oguz

Oct 12 '06 #1
12 1644
eastern_strider wrote:
Hi,

Is it safe to have a pointer to a string.c_str() created locally inside
a function?
No.
For example, would the following code give me headace if a
try to use "c" after calling foo() ?

const char *c;

void foo ()
{
string str = "Hello";
c = str.c_str();
}
You shouldn't do this. You can normally call functions that take a
C-style string without any problems (as long as they don't modify the
string) as these normally just copy the string into their own internal
buffer. However, having pointers to char in your own code is just a bad
idea. Why not just have a string object that holds the string?

Regards,
Bart.

Oct 12 '06 #2
eastern_strider wrote:
Hi,

Is it safe to have a pointer to a string.c_str() created locally
inside a function? For example, would the following code give me
headace if a try to use "c" after calling foo() ?

const char *c;

void foo ()
{
string str = "Hello";
c = str.c_str();
}
Yes, it would. str ceases to exist at the end of that scope, and any
memory it allocated is almost suredly deallocated. Otherwise every use
of a string would be memory leak.


Brian


Oct 12 '06 #3
I'm not quite sure about the memory being deallocated at the end of the
function. I've run into several instances where I've had memory leaks
from CStrings that haven't been deallocated.

If I remember correctly there are functions inside CString to help
clean up. I don't remember the exact function calls, but they were
something to the extent of "EmptyStringContents" and then
"FreeUnusedMemory".

On Oct 12, 4:44 pm, "Default User" <defaultuse...@yahoo.comwrote:
eastern_strider wrote:
Hi,
Is it safe to have a pointer to a string.c_str() created locally
inside a function? For example, would the following code give me
headace if a try to use "c" after calling foo() ?
const char *c;
void foo ()
{
string str = "Hello";
c = str.c_str();
}Yes, it would. str ceases to exist at the end of that scope, and any
memory it allocated is almost suredly deallocated. Otherwise every use
of a string would be memory leak.

Brian
Oct 13 '06 #4
On Oct 12, 4:44 pm, "Default User" <defaultuse...@yahoo.comwrote:
>eastern_strider wrote:
>>Hi,
Is it safe to have a pointer to a string.c_str() created locally
inside a function? For example, would the following code give me
headace if a try to use "c" after calling foo() ?
const char *c;
void foo ()
{
string str = "Hello";
c = str.c_str();
}Yes, it would. str ceases to exist at the end of that scope, and any
memory it allocated is almost suredly deallocated. Otherwise every use
of a string would be memory leak.

Brian
tugboat90 wrote:
I'm not quite sure about the memory being deallocated at the end of the
function. I've run into several instances where I've had memory leaks
from CStrings that haven't been deallocated.

If I remember correctly there are functions inside CString to help
clean up. I don't remember the exact function calls, but they were
something to the extent of "EmptyStringContents" and then
"FreeUnusedMemory".
Please don't top-post...

A C++ std::string is NOT a CString.

CString is Microsoft specific.

std::string does not have cleanup issues.
Oct 13 '06 #5
"eastern_strider" <og*******@gmail.comwrote in message
news:11*********************@m7g2000cwm.googlegrou ps.com...
Hi,

Is it safe to have a pointer to a string.c_str() created locally inside
a function? For example, would the following code give me headace if a
try to use "c" after calling foo() ?

const char *c;

void foo ()
{
string str = "Hello";
c = str.c_str();
}
Yes and No. It depends on what you plan on doing with the string pointer
after you assign it. The pointer returned to by .c_str() will remain valid
until the std::string is changed somehow (characters added, erased, etc..)
or the std::string goes out of scope. With such limitations it's easy to
get bitten by the data becoming invalid. If you have an extremely good
reason for doing this (and I actually can't think of one), and document it
in code, and know what you're doing, it should be okay, but with all tose
this and that and that, it is safer, IMO, just not to do that.

So the question becomes, *why* would you want to assign the pointer returned
via .c_str() to a variable? For what purpose? It is a constant c-string
and so you can't change the data. So why do you need to keep the pointer
around?
Oct 13 '06 #6

eastern_strider wrote:
Hi,

Is it safe to have a pointer to a string.c_str() created locally inside
a function? For example, would the following code give me headace if a
try to use "c" after calling foo() ?

const char *c;

void foo ()
{
string str = "Hello";
c = str.c_str();
}
No, as others have pointed out c becomes a stale pointer as soon as
foo() returns to its caller.

As a rule of thumb, call std::string::c_str() only when passing the
contents of a std::string object to a function that expects a const
char * parameter (such as many POSIX routines). Limiting
std::string-to-C-string-pointer conversions to this one case ensures
that the converted const char * pointer never becomes stale. Otherwise,
just use std::string's consistently throughout the rest of your code.

Greg

Oct 13 '06 #7
eastern_strider wrote:
Hi,

Is it safe to have a pointer to a string.c_str() created locally inside
a function? For example, would the following code give me headace if a
try to use "c" after calling foo() ?

const char *c;

void foo ()
{
string str = "Hello";
c = str.c_str();
}
Yes, this program will have a serious problem: as others have pointed
out c becomes a stale pointer as soon as foo() returns to its caller.

As a rule of thumb, call std::string::c_str() only when passing the
contents of a std::string object to a function that expects a const
char * parameter (such as many POSIX routines). Limiting
std::string-to-C-string-pointer conversions to this one case ensures
that the converted const char * pointer never becomes stale. Otherwise,
just use std::string's consistently throughout the rest of your code.

Greg

Oct 13 '06 #8
Hi,

Thanks for all replies. I've just given the sample code for
illustration and what I'm exactly doing is very similar to Greg's
example.

I'm using an external library function which accepts c-style strings as
argument. However, it just keeps a pointer to this argument. That is,
it DOES NOT actually copy it to an internal buffer. So my real use of
c_str() is just like:

MyClass::MyClass()
{
string str = "Hello";
BaseClass::add (str.c_str());
}

Now what "add" does is:

void BaseClass::add (const char *item)
{
item_ptr = item; // item_ptr is a const char* member of BaseClass
}

So this is the whole story. The question is, throughout the rest of the
program, does item_ptr continue to point to a valid location? I
believe I can ensure that explicitly by definining:

string* str = new string ("Hello");

inside my constructor. However, I've been wondering whether such an
explicit allocation is actually necessary in this case.

All answers are very much appreciated.
Oguz

Greg wrote:
eastern_strider wrote:
Hi,

Is it safe to have a pointer to a string.c_str() created locally inside
a function? For example, would the following code give me headace if a
try to use "c" after calling foo() ?

const char *c;

void foo ()
{
string str = "Hello";
c = str.c_str();
}

Yes, this program will have a serious problem: as others have pointed
out c becomes a stale pointer as soon as foo() returns to its caller.

As a rule of thumb, call std::string::c_str() only when passing the
contents of a std::string object to a function that expects a const
char * parameter (such as many POSIX routines). Limiting
std::string-to-C-string-pointer conversions to this one case ensures
that the converted const char * pointer never becomes stale. Otherwise,
just use std::string's consistently throughout the rest of your code.

Greg
Oct 13 '06 #9
eastern_strider wrote:
>
I'm using an external library function which accepts c-style strings as
argument. However, it just keeps a pointer to this argument. That is,
it DOES NOT actually copy it to an internal buffer. So my real use of
c_str() is just like:

MyClass::MyClass()
{
string str = "Hello";
BaseClass::add (str.c_str());
}

Now what "add" does is:

void BaseClass::add (const char *item)
{
item_ptr = item; // item_ptr is a const char* member of BaseClass
}
Why not:

void BaseClass::add (const std::string& item )
{
_sitem = item;
my_ext_library_which_accepts_cstrings(_sitem.c_str ());
}
So this is the whole story. The question is, throughout the rest of the
program, does item_ptr continue to point to a valid location?
No, since the std::string "str" gets out of scope and the memory it
contained is deleted. As pointed out earlier.
I believe I can ensure that explicitly by definining:

string* str = new string ("Hello");
You don't have to use pointers. If you pass a C style string to the
constructor of an std::string it automatically creates a copy of the
string.

I urge you to get a C++ book.

Oct 13 '06 #10

eastern_strider wrote:
Hi,

Thanks for all replies. I've just given the sample code for
illustration and what I'm exactly doing is very similar to Greg's
example.

I'm using an external library function which accepts c-style strings as
argument. However, it just keeps a pointer to this argument. That is,
it DOES NOT actually copy it to an internal buffer. So my real use of
c_str() is just like:

MyClass::MyClass()
{
string str = "Hello";
BaseClass::add (str.c_str());
}

Now what "add" does is:

void BaseClass::add (const char *item)
{
item_ptr = item; // item_ptr is a const char* member of BaseClass
}

So this is the whole story. The question is, throughout the rest of the
program, does item_ptr continue to point to a valid location? I
believe I can ensure that explicitly by definining:

string* str = new string ("Hello");

inside my constructor. However, I've been wondering whether such an
explicit allocation is actually necessary in this case.
item_ptr is not valid. You'll need to manage the allocation of a
std::string. That does not mean you need a heap allocation. You can
keep a const std::string member in MyClass. You'll need to observe
what, if any, ctor is available for that BaseClass.

Now there are 2 issues you need to be aware of: copy ctors and
inheritence.
What follows is not neccessarily correct for you. You may prefer
overiding add(...).

#include <string>

class MyClass : public BaseClass
{
const std::string s_;
public:
MyClass(std::string s) : BaseClass() : s_(s)
{
add(s_.c_str());
}
MyClass(const MyClass& r_copy) : BaseClass(), s_(r_copy.s_) // const
{
add(s_.c_str()); // reseated pointer
}
};

If you need to copy an instance of MyClass, you certainly don't want
the BaseClass pointer (const char* item) to point to the original
instance. If you don't plan to copy at all, disable copy construction.
Better an error than a bug you'll regret.

class MyClass : public BaseClass
{
const std::string s_;
public:
MyClass(std::string s) : BaseClass() : s_(s)
{
add(s_.c_str());
}
MyClass(const MyClass& r_copy); // disabled
};

Lastly: inheritence.
Don't use pointers to BaseClass objects to store MyClass instances if
BaseClass does not have a virtual d~tor. I'm willing to bet that the
BaseClass is using a non-virtual compiler-generated ctor.

Finally, don't use pointers unless you absolutely have to. Always
prefer references.

Oct 13 '06 #11
Thanks for your kind! reply, but it seems misleading to me.

Please correct me if I'm wrong but you suggest that:

const char* foo ()
{
std::string str ("Hello");
return str.c_str();
}

int main()
{
const char *c = foo();
// c can be used safely in the rest of the program.
}

I'm not sure that this is as safe as:

const char* foo ()
{
std::string* str = new string ("Hello");
return str->c_str();
}

because in the latter we guarantee that the memory associated with str
will continue to exist even after foo returns. However, in the former
version that memory might be freed once foo returns since str is a
local variable.

Cheers,
Oguz


Florian Stinglmayr wrote:
eastern_strider wrote:

I'm using an external library function which accepts c-style strings as
argument. However, it just keeps a pointer to this argument. That is,
it DOES NOT actually copy it to an internal buffer. So my real use of
c_str() is just like:

MyClass::MyClass()
{
string str = "Hello";
BaseClass::add (str.c_str());
}

Now what "add" does is:

void BaseClass::add (const char *item)
{
item_ptr = item; // item_ptr is a const char* member of BaseClass
}

Why not:

void BaseClass::add (const std::string& item )
{
_sitem = item;
my_ext_library_which_accepts_cstrings(_sitem.c_str ());
}
So this is the whole story. The question is, throughout the rest of the
program, does item_ptr continue to point to a valid location?

No, since the std::string "str" gets out of scope and the memory it
contained is deleted. As pointed out earlier.
I believe I can ensure that explicitly by definining:

string* str = new string ("Hello");

You don't have to use pointers. If you pass a C style string to the
constructor of an std::string it automatically creates a copy of the
string.

I urge you to get a C++ book.
Oct 13 '06 #12

On Oct 13, 9:26 am, "eastern_strider" <oguzak...@gmail.comwrote:
Thanks for your kind! reply, but it seems misleading to me.

Please correct me if I'm wrong but you suggest that:

const char* foo ()
{
std::string str ("Hello");
return str.c_str();

}int main()
{
const char *c = foo();
// c can be used safely in the rest of the program.
NOOO ! Noone is suggesting this - it doesn't work. str goes out of
scope when you exit foo and the buffer returned is therefore invalid.
>
const char* foo ()
{
std::string* str = new string ("Hello");
return str->c_str();

}
This is also wrong but for a different reason - the memory will not be
freed (there is no "might" about it) so although you can use the
returned const char* safely, you now have a memory leak because you
have no way of destroying the newed string.

You have to get what's happening with local and heap-based objects
clear in your head to be able to use C++ properly.

Oct 13 '06 #13

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

Similar topics

16
by: Krakatioison | last post by:
My sites navigation is like this: http://www.newsbackup.com/index.php?n=000000000040900000 , depending on the variable "n" (which is always a number), it will take me anywhere on the site......
5
by: Stu Cazzo | last post by:
I have the following: String myStringArray; String myString = "98 99 100"; I want to split up myString and put it into myStringArray. If I use this: myStringArray = myString.split(" "); it...
9
by: John F Dutcher | last post by:
I use code like the following to retrieve fields from a form: recd = recd.append(string.ljust(form.getfirst("lname",' '),15)) recd.append(string.ljust(form.getfirst("fname",' '),15)) etc.,...
10
by: Angus Leeming | last post by:
Hello, Could someone explain to me why the Standard conveners chose to typedef std::string rather than derive it from std::basic_string<char, ...>? The result of course is that it is...
2
by: Andrew | last post by:
I have written two classes : a String Class based on the book " C++ in 21 days " and a GenericIpClass listed below : file GenericStringClass.h // Generic String class
29
by: zoro | last post by:
Hi, I am new to C#, coming from Delphi. In Delphi, I am using a 3rd party string handling library that includes some very useful string functions, in particular I'm interested in BEFORE (return...
2
by: Badass Scotsman | last post by:
Hello, Using VB and ASP,NET I would like to be able to search a STRING for a smaller STRING within, based on the characters which appear before and after. For example: String1 = " That was...
15
by: morleyc | last post by:
Hi, i would like to remove a number of characters from my string (\t \r \n which are throughout the string), i know regex can do this but i have no idea how. Any pointers much appreciated. Chris
11
by: ramu | last post by:
Hi, Suppose I have a string like this: "I have a string \"and a inner string\\\" I want to remove space in this string but not in the inner string" In the above string I have to remove...
8
by: drjay1627 | last post by:
hello, This is my 1st post here! *welcome drjay* Thanks! I look answering questions and getting answers to other! Now that we got that out of the way. I'm trying to read in a string and...
0
by: ryjfgjl | last post by:
ExcelToDatabase: batch import excel into database automatically...
0
isladogs
by: isladogs | last post by:
The next Access Europe meeting will be on Wednesday 6 Mar 2024 starting at 18:00 UK time (6PM UTC) and finishing at about 19:15 (7.15PM). In this month's session, we are pleased to welcome back...
0
by: Vimpel783 | last post by:
Hello! Guys, I found this code on the Internet, but I need to modify it a little. It works well, the problem is this: Data is sent from only one cell, in this case B5, but it is necessary that data...
0
by: jfyes | last post by:
As a hardware engineer, after seeing that CEIWEI recently released a new tool for Modbus RTU Over TCP/UDP filtering and monitoring, I actively went to its official website to take a look. It turned...
0
by: ArrayDB | last post by:
The error message I've encountered is; ERROR:root:Error generating model response: exception: access violation writing 0x0000000000005140, which seems to be indicative of an access violation...
1
by: PapaRatzi | last post by:
Hello, I am teaching myself MS Access forms design and Visual Basic. I've created a table to capture a list of Top 30 singles and forms to capture new entries. The final step is a form (unbound)...
1
by: CloudSolutions | last post by:
Introduction: For many beginners and individual users, requiring a credit card and email registration may pose a barrier when starting to use cloud servers. However, some cloud server providers now...
0
by: Faith0G | last post by:
I am starting a new it consulting business and it's been a while since I setup a new website. Is wordpress still the best web based software for hosting a 5 page website? The webpages will be...
0
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 3 Apr 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome former...

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.