473,779 Members | 1,912 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

char* dynamic strings - the right way

What is the right way of creating a string/char array and assigning to
a char* which is then used in a function call. Thought it would be
quite nice to avoid a memory leakage /core dump.

1 Header with char* x

2 Class includes header

3 In Class member function I want to :
a)conditionally create a string ie populate x
b)pass (populated) x on as a function parameter.

What is the right way of doing this for :
i) assigning string variable
ii) assigning a literal.

i) Since it's a conditional create I guess it is not a good idea to use
malloc or new.

ii) Is it ok to just have x = "some string";

Nov 8 '05
16 2426

John Harrison wrote:
dr******@gmail. com wrote:
I do not know the correct way of doing this - that is why I am posting
here!

1. You have a char *
2. You need to go off and populate this with a string or char array but
you do not know the size of the string., so....
3. string seems to be 'the' way of doing this but
a) c_str() returns a const and needs casting using char*
b) although the c_str() casting works and it is possible to print
the string out later - is this a case of something that will work
but not always?


You need to allocate memory

string s = "qwerty";
char* ptr = new char[s.size() + 1];
strcpy(ptr, s.c_str());
...
// sometime later when you are done
delete[] ptr;

It's because of this mess (particularly the need to delete[]) that you
should use strings instead of char, if you possibly can.

john


thanks John, I was hoping there was a better way.
Maybe that the string for object string s would remain
while it had a reference to it and remove it once that
reference is removed - but maybe thats java.

So my program above becomes:

void f2(string &s)
{
s="qwerty";
}
void f1(myStruct &ms)
{
string s;

f2(s);
// Error 203: # Cannot assign 'char *' with 'const char *'.
//ms.cp = s.c_str();

ms.cp = new char[s.size() + 1];
strcpy(ptr, s.c_str());

// and not ms.cp = (char*)s.c_str( );
}
int main () {
myStruct mystruct;

f1(mystruct);
cout << mystruct.cp << endl;
delete [] ms.cp;

return 0;
}

Nov 22 '05 #11
> int main () {
myStruct mystruct;

f1(mystruct);
cout << mystruct.cp << endl;
delete [] ms.cp;

return 0;
}


To find out whether this will work, I have to see what myStruct looks
like. Looks bad, though. Show us <myStruct> definition, then I'll
comment.

Regards,

Werner

Nov 22 '05 #12

werasm wrote:
int main () {
myStruct mystruct;

f1(mystruct);
cout << mystruct.cp << endl;
delete [] ms.cp;

return 0;
}


To find out whether this will work, I have to see what myStruct looks
like. Looks bad, though. Show us <myStruct> definition, then I'll
comment.

Regards,

Werner


Whoops sorry,

typedef struct {
char *cp;
} myStruct ;

Nov 22 '05 #13
dr******@gmail. com wrote:
Whoops sorry,

typedef struct {
char *cp;
} myStruct ;


I've looked at your example. It does not compile, firstly - where is
ptr declared in f1 (I'll assume you've meant ms.cp)? Also, the strcpy
omits copying the NULL terminator. This would mean streaming the
NON-terminated string to std::cout would envoke undefined behaviour, if
I'm not mistaken. All of this could have been achieved using:

int main()
{
std::cout << qwerty << std::endl;
return 0;
}

I don't see the point. Also, myStruct does not overload a copy
constructor/assignment operator/destructor. In general, the code is
bad. The only thing you are doing right, is that you call operator
delete[] when creating with operator new[] - good.

W

Nov 22 '05 #14
Thank you for looking at the code and apologies for the compile error.
Here is the compiled version:

typedef struct {
char *cp;
} myStruct ;

void f2(string &s)
{
s="qwerty";

}

void f1(myStruct &ms)
{
string s;

f2(s);

ms.cp = new char[s.size() + 1];
strcpy(ms.cp, s.c_str());
ms.cp[s.size()]='\0';
}

int main () {
myStruct mystruct;

f1(mystruct);
cout << mystruct.cp << endl;
delete [] mystruct.cp;

return 0;
}

Please bear in mind I have created a simplified example to illustrate a
problem. The premise is having to deal with populating existing chars :
a one line cout statement isn't really the answer.

Nov 22 '05 #15

dr******@gmail. com wrote:
Thank you for looking at the code and apologies for the compile error.
Here is the compiled version:

typedef struct {
char *cp;
} myStruct ;
In c++ the typedef is redundant, therefore ...

struct myStruct
{
char* cp;
};
.... would have sufficed.

void f2(string &s)
{
s="qwerty";

}
Even for you example, this (above) is unecessary.

void f1(myStruct &ms)
{
string s;

f2(s);

This could be:
std::string s( "qwerty" );

In general, it is good to qualify the std items explicitly.
ms.cp = new char[s.size() + 1]; Yes, this is how you allocate memory for the array. The size allocated
is correct as you require provision for a NULL terminator. s.size does
return the size of string excluding NULL terminator.
strcpy(ms.cp, s.c_str());
I would have used strncpy (or char_traits::co py) over here (actually I
would use strings :-) ).

strncpy( ms.cp, s.c_str(), s.size() )[s.size()] = '\0';

Note strncpy actually returns the destination string, therefore you
could use above syntax to terminate.
int main () { I would not have made char* part of struct.
myStruct mystruct;
char* myChar;

f1(myChar);

f1 then has signature <char*&>. IMO this still does not convey the
intent of the function, and it does not indicate to the receiver of
char* that he is required to delete it. It is less work and has the
same effect as your example though.

Therefore:

void f1( char*& out )
{
std::string qstr( "qwerty" );
const unsigned outSz( qstr.size()+1 );

out = new char[ outSz];
strncpy( out, qstr.c_str(), outSz-1 )[outSz];
}

int main()
{
char* myChar( 0 );
f1( myChar );
if( myChar )
{
std::cout << myChar << std::endl;
delete [] myChar;
}
return 0;
}

Also note that deleting a NULL ptr is valid, but sending NULL ptr to
std::cout may not be.

Kind regards,

W

Nov 22 '05 #16

werasm wrote:
dr******@gmail. com wrote:
Thank you for looking at the code and apologies for the compile error.
Here is the compiled version:

typedef struct {
char *cp;
} myStruct ;
In c++ the typedef is redundant, therefore ...

struct myStruct
{
char* cp;
};
... would have sufficed.

void f2(string &s)
{
s="qwerty";

}


Even for you example, this (above) is unecessary.

void f1(myStruct &ms)
{
string s;

f2(s);


This could be:
std::string s( "qwerty" );

In general, it is good to qualify the std items explicitly.
ms.cp = new char[s.size() + 1];

Yes, this is how you allocate memory for the array. The size allocated
is correct as you require provision for a NULL terminator. s.size does
return the size of string excluding NULL terminator.
strcpy(ms.cp, s.c_str());


I would have used strncpy (or char_traits::co py) over here (actually I
would use strings :-) ).

strncpy( ms.cp, s.c_str(), s.size() )[s.size()] = '\0';

Note strncpy actually returns the destination string, therefore you
could use above syntax to terminate.


Actually, this is not necessary in this case, as the source is
guaranteed to be terminated, and strncpy reads until it finds a
terminator, then pads the rest therefore the above statement can
become:

strncpy( ms.cp, s.c_str(), s.size()+1 );

This will ensure ms.cp is terminated :-).
int main () { I would not have made char* part of struct.
myStruct mystruct;


char* myChar;

f1(myChar);

f1 then has signature <char*&>. IMO this still does not convey the
intent of the function, and it does not indicate to the receiver of
char* that he is required to delete it. It is less work and has the
same effect as your example though.

Therefore:

void f1( char*& out )
{
std::string qstr( "qwerty" );
const unsigned outSz( qstr.size()+1 );

out = new char[ outSz];
strncpy( out, qstr.c_str(), outSz-1 )[outSz];


Note that above statement should actually be...

strncpy( out, qstr.c_str(), outSz );

.... for reasons previously mentioned.
}

int main()
{
char* myChar( 0 );
f1( myChar );
if( myChar )
{
std::cout << myChar << std::endl;
delete [] myChar;
}
return 0;
}

Also note that deleting a NULL ptr is valid, but sending NULL ptr to
std::cout may not be.

Kind regards,

W


Nov 23 '05 #17

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

Similar topics

1
18011
by: Matt Garman | last post by:
What is the "best" way to copy a vector of strings to an array of character strings? By "best", I mean most elegantly/tersely written, but without any sacrifice in performance. I'm writing an application using C++ and the STL for handling my data. Unfortunately, I must interact with a (vanilla) C API. I use vectors of strings (for simplicity and less memory hassle), but the function calls for this API require arrays of character...
3
2212
by: sieg1974 | last post by:
Hi, I have made this simple program to understand char ** pointers, but I still having many questions. int main() { char ** testPointerPointerChar = 0; char * A = "string01";
2
5352
by: collinm | last post by:
hi i expect to find 7 file on a folder... maybe less, maybe more... i can surely put this number to 1... but i think doing some realloc will be expensive... after 7 files, i need to use realoc... somebody could help me to use realloc?
7
5640
by: arkobose | last post by:
hey everyone! i have this little problem. consider the following declaration: char *array = {"wilson", "string of any size", "etc", "input"}; this is a common data structure used to store strings of any lengths into an array of pointers to char type variable. my problem is: given the declaration
12
9585
by: leonard.guillaume | last post by:
Hi guys, I use dynamic char arrays and I'm trying to get rid of the garbage in it. Let me show you the code and then I'll explain more in details. ---------------------------------------------------------------------------------------------------- CFile oFile("User.tcx", CFile::modeRead); CRijndael oDecrypt; long size; char* buffer,* buf;
33
3679
by: Jordan Tiona | last post by:
How can I make one of these? I'm trying to get my program to store a string into a variable, but it only stores one line. -- "No eye has seen, no ear has heard, no mind can conceive what God has prepared for those who love him" 1 Cor 2:9
3
11780
by: DG is a god.... | last post by:
Dear All , This is my first post - please go easy...! I have a DLL written in C++ that has the following function exported from it -: char** ListHandles(int *processID); The processID parameter is used to find all associated open file
18
4064
by: Pedro Pinto | last post by:
Hi there once more........ Instead of showing all the code my problem is simple. I've tried to create this function: char temp(char *string){ alterString(string); return string;
12
3016
blackstormdragon
by: blackstormdragon | last post by:
Im having trouble with my classList variable. It's a dynamic array of strings used to store the names of the classes(my program ask for students name, number of classes, then a list of the classes). typedef char* CharPtr; class Student { public: Student& operator =(const Student& rightside); ~Student();
0
9632
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, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10136
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
10071
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
9925
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
8958
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
5372
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...
0
5501
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4036
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
2
3631
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.

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.