473,405 Members | 2,167 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,405 software developers and data experts.

Using operator new in function call and what the expr evaluates to

Consider this code that doesn't compile on two compilers I've tried:

void foo(const char *) {}

int main()
{
foo(new const char * ("bar"));
}

$ g++ -Wall -Wextra -std=c++98 -pedantic -g cpptest.cpp -o runme
cpptest.cpp: In function `int main()':
cpptest.cpp:7: error: cannot convert `const char**' to `const char*'
for argument `1' to `void foo(const char*)'

I came across this when I used a third party gui library and wanted to
associate a string with a gui control. The gui control stores some
integer type as its user value (that is normally a pointer) so I was
casting to that when calling my function and the compiler was happy
but I noticed the stored string was garbage when I retrieved it later.
And when I changed the signature of the function to take a pointer to
const char instead and only cast at the last possible instant I got an
error (and the explanation why the text I ended up storing was
garbage). It's just that I don't understand why that does not work.

May 20 '07 #1
3 1362
Eric Lilja wrote:
Consider this code that doesn't compile on two compilers I've tried:

void foo(const char *) {}

int main()
{
foo(new const char * ("bar"));
}

$ g++ -Wall -Wextra -std=c++98 -pedantic -g cpptest.cpp -o runme
cpptest.cpp: In function `int main()':
cpptest.cpp:7: error: cannot convert `const char**' to `const char*'
for argument `1' to `void foo(const char*)'
A literal string (i.e. "bar") evaluates to a const char [4], however a
special case in the C++ standard (which it should never have been placed
in the standard) is that a literal string can convert to a "char *"
without warning (which is irrelevant in this case but it's important to
be complete).

The compiler is telling you ...
cannot convert `const char**' to `const char*'

The way to do this is create a string factory - i.e.

const char * Factory( const char * v ) {
int len = strlen(v)+1
char * x = new char [len];
memcpy( x, v, len );
return x;
}

But then, who is responsible for calling delete[] on strings from
Factory() ?
>
I came across this when I used a third party gui library and wanted to
associate a string with a gui control.
Did the gui control delete[] the strings ? Did it make it's own copy ?
... The gui control stores some
integer type as its user value (that is normally a pointer) so I was
casting to that when calling my function and the compiler was happy
but I noticed the stored string was garbage when I retrieved it later.
And when I changed the signature of the function to take a pointer to
const char instead and only cast at the last possible instant I got an
error (and the explanation why the text I ended up storing was
garbage). It's just that I don't understand why that does not work.
Don't understand what does not work ?

If it's the "new const char * ("bar")" then it's because it's wrong,
plain and simple.

If it's because you have garbage, well, maybe it's because you do have
pointers to strings stored in your GUI thing that get modified at a
later time.

Is there any way your GUI thing can inform you that it's being deleted ?
That way you can hook into it to delete your string. Does your GUI
type have a virtual destructor ? If so, you can just derive from it and
provide your own destruction mechanism.
May 20 '07 #2
void foo(const char *) {}

int main()
{
foo(new const char * ("bar"));
}
.....
It's just that I don't understand why that does not work.
Well, when you do 'new int' you get 'int*' as a return type. When you
do 'new char*' you obviously get a 'char**' as a return type. For this
to compile put deref in front of new:

foo(* new const char *("bar"));

But that would make a pointer-size memory leak ;] and wouldnt copy
anything xept "bar" base address. So you could pass "bar" to your foo
with same success and no memory leaks ;].

if you dont like patternish factory talk, you can do this

foo( strcpy( new char [sizeof("bar")], "bar") );

but this looks no less ugly I think ;]

so maybe smthing like

template <int N>
const char* copystr(const char (&str)[N] )
{
return strcpy( new char[N], str );
}
....
foo(copystr("bar"));

but still dont forget to delete this all later.

Btw storing 'const char*' as 'int' is fine unless you're on 64 bit
platform (or some other weird platform where sizeof(const char*) !=
sizeof(int)). So maybe you just retreived it back wrong, or your code
have overwritten it due to some buffer overrun or smth else.

May 20 '07 #3
an*******@ukr.net wrote:
>void foo(const char *) {}

int main()
{
foo(new const char * ("bar"));
}
....
>It's just that I don't understand why that does not work.

Well, when you do 'new int' you get 'int*' as a return type. When you
do 'new char*' you obviously get a 'char**' as a return type. For this
to compile put deref in front of new:

foo(* new const char *("bar"));

But that would make a pointer-size memory leak ;] and wouldnt copy
anything xept "bar" base address. So you could pass "bar" to your foo
with same success and no memory leaks ;].

if you dont like patternish factory talk, you can do this

foo( strcpy( new char [sizeof("bar")], "bar") );
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Pick your mistake.
>
but this looks no less ugly I think ;]
Too error prone.
>
so maybe smthing like

template <int N>
const char* copystr(const char (&str)[N] )
{
return strcpy( new char[N], str );
}
You have N. Why not use memcpy ?
...
foo(copystr("bar"));

but still dont forget to delete this all later.

Btw storing 'const char*' as 'int' is fine unless you're on 64 bit
platform (or some other weird platform where sizeof(const char*) !=
sizeof(int)). So maybe you just retreived it back wrong, or your code
have overwritten it due to some buffer overrun or smth else.
Yes, good point. The other option is to place your pointers in a vector
and manage the vector with new strings.
May 20 '07 #4

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

Similar topics

3
by: Guy Robinson | last post by:
I have the code below which parses an expression string and creates tokens. Can anyone suggest the best of error checking for things like: Valid variable only obj.attribute -whitespace allowed...
7
by: Koster | last post by:
Hi folks, As I understand it, amongst other things, the comma operator may be used to cause any number of expressions to be evaluated (who's results are thrown away except the last) where only...
21
by: kimimaro | last post by:
Is there anymore methods in exiting your program using pure C language other than return 0?
17
by: Anoob | last post by:
Can we consider () unary operator when calling a function, in exps eq. f(), ( 1 + 2). But when we call function f( 10 ) it is a binary operator. Even if we pass f( 10, 20) as we are using ,...
4
by: G Patel | last post by:
Hi, I've read a book on C, and I understand how comma operators work, but my book didn't say that the comma operators between function arguments were not really comma operators (even though it...
2
by: Jake Barnes | last post by:
Using javascript closures to create singletons to ensure the survival of a reference to an HTML block when removeChild() may remove the last reference to the block and thus destory the block is...
2
by: korean44 | last post by:
A beginner in C# .. I wrote 2 classes like below.. (psuedo code) public class FormUI : System.Windows.Forms.Form { public TextBox tbResult = new TextBox(); ...
9
by: marko | last post by:
/* code start */ int a = 0; /* expected evaluation and excution order with precedence in mind /* False(3) , True(1), False(2) */ if ( (a=1) == 0 || 0 != 1 && (a =2) == 1) putchar('T');...
3
by: Andrew Poulos | last post by:
Why is it that if I do this: Foo = function() { this.prop = true; }; Foo.prototype.hi = function() { alert("hi"); }; bar = new Foo(); delete bar;
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However,...
0
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,...
0
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...
0
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...

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.