char table / pointer memory allocation

M

mehafi

Hi,

Why this program work?

#include<iostream.h>
class test
{
public:
char *ptr;
void setPtr(char* p){
ptr = p;
}
void print(){
cout << ptr << endl;
}
};

main()
{
test t;
t.setPtr("abc");
t.print();
system("pause");
}

Is argument of function setPtr - "abc" - a temporary char table, made
on stack, which is deleted when setPtr function ends? If it is, the
pointer - ptr - point then to the memory addres which was deleted, so
print method should print random characters or may crash the program.
When I made char table using new:

main()
{
char* tab = new char[4];
strcpy(tab, "abc");
test t;
t.setPtr(tab);
delete[] tab;
t.print();
system("pause");
}

print() method prints random characters.
But why the first program doesn't crash / prints random chars ?

thanks in advance
best regards
mehafi
 
S

sk_usenet

Why this program work?

#include<iostream.h>

Non standard header. Get any recent book on C++ that would explain why this
is not portable.
class test
{
public:
char *ptr;
void setPtr(char* p){
ptr = p;
}
void print(){
cout << ptr << endl;
}
};

main()

You need an explicit "int main()".
{
test t;
t.setPtr("abc");
t.print();
system("pause");
}

Is argument of function setPtr - "abc" - a temporary char table, made
on stack, which is deleted when setPtr function ends? If it is, the

"abc" is not on stack, it's a string literal and has static storage
duration.
The storage for these objects shall last for the duration of the program
pointer - ptr - point then to the memory addres which was deleted, so
print method should print random characters or may crash the program.
When I made char table using new:

What's a char table?
main()
{
char* tab = new char[4];
strcpy(tab, "abc");
test t;
t.setPtr(tab);
delete[] tab;
t.print();
system("pause");
}

print() method prints random characters.

Because of undefined behavior.
But why the first program doesn't crash / prints random chars ?

Read above.
 
J

James Kanze

(e-mail address removed) wrote in @f36g2000hsa.googlegroups.com:
Besides, I recommend to get familiar with std::string and
forget the string lifetime issues forever.

I can't let that pass. The only times I use C style strings is
when lifetime is an issue; a static char[] with a constant
initializer is static initialized, and effectively has an
infinite lifetime. A static std::string can easily be accessed
before it is constructed, or after it is destructed.
 
J

James Kanze

(e-mail address removed):
(e-mail address removed) wrote in @f36g2000hsa.googlegroups.com:
Besides, I recommend to get familiar with std::string and
forget the string lifetime issues forever.
I can't let that pass. The only times I use C style strings is
when lifetime is an issue; a static char[] with a constant
initializer is static initialized, and effectively has an
infinite lifetime.
And not much of use in a multithreaded application
(presumably, char[] array is used for changing the content,
otherwise one should just use string literals).

A string literal is a char[]. (OK, a char const[].) But the
char[] will often occur in structures. A char const* is more
usual, but there are exceptions. (And of course, the char
const* points to a char const[], usually a string literal.)
Any global mutable object will create problems in
multithreaded environment (and if you are writing a library
you don't know if it is going to be used in singlethreaded or
multithreaded fashion).

That depends on the library, and the targetted users. I know
that the ones I work on professionally will be used in a
multithreaded environment, since they create threads themselves.
A static char[] has to be externally locked by each access.
This should better be encapsulated in a class managing this
string - and voila, we are back to the statics initialization
order problem. One needs singleton pattern or something
similar here. And in a singleton one could easily use
std::string as well.
A static std::string can easily be accessed before it is
constructed, or after it is destructed.
Yes, avoid namespace-level statics, these are evil ;-) (no pun
intended!).

Local statics aren't necessarily any better. In fact, they can
be worse, since they aren't necessarily constructed before main.

In the end, the surest bet is statically initialized constant
values. They're guaranteed to be initialized before any code
actually runs. Thus, for example, I'll often use a statically
initialized struct Something const [] and std::find_if, rather
than std::map, because it is 100% free of order of
initialization issues.
Note also that a static char[] array is of limited size.

Yes, but the compiler will define the size in accordance with
the initializer.
The size should be checked explicitly by every mutating
operation, which does not sound very reliable. I would argue
this solution has problems even in single- threaded code.

Nobody suggested using char[] for mutable objects.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,769
Messages
2,569,580
Members
45,054
Latest member
TrimKetoBoost

Latest Threads

Top