473,385 Members | 1,736 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,385 software developers and data experts.

Strings vs char* and strcpy()

Hi,

I wonder if anyone could point me in the direction of a discussion on
the similarities and differences between the C++ String type and char*
strings?

The reason I ask is because I am working on a legacy application using
the old C socket.h library. The send function accepts the message to be
sent as a char*.

I am having problems making a deep copy of a char* string in C++.

Consider the following code sample:

class Message {

public:

Message () : unsent(NULL) {
};

void Add(char*);
void Del();
char* GetMsg();
void ShiftMsg(int);

~Message() {
Del();
}

private:

char* wholeMessage;
char* unsentBytes;

};

//Create deep copy of inmessage
void Message::Add (char* inmessage) {

wholeMessage = new char[strlen(inmessage) + 1];

strcpy(wholeMessage,inmessage);

unsentBytes = wholeMessage;

}

//Release memory allocated to wholeMessage
void Message::Del() {

if (wholeMessage != NULL) {
delete [] wholeMessage;
}
unsentBytes = NULL;

}

//Get unsent portion of message
char* Message::GetUnsent() {

if (unsentBytes == NULL) {
return "";
}
else {
return unsentBytes;
}
}

//Increment unsentBytes pointer to point at unsent portion of
//message
void Message::ShiftMsg(int bytesSent) {
unsentBytes = unsentBytes + bytesSent;
}
I have a problem. When I attempt to allocate the momory for
wholeMessage using the new operator I get an access violation yet I do
not understand why. Can anyone explain what I am doing wrong?

I realise that I probably *should* be using C++ String types to store
my message. I know that I can allocate a char* to a String variable but
does it work the other way round? Can I pass a String to a function
expecting a char*

Finally, a question about general style. I feel I should be creating a
new instance of Message for each string I am processing and destroying
it once sent but this would involve me creating and destroying hundreds
of instances a second. Is there a large overhead involved in doing
this?

Many thanks for any help.

Lawrie.

Jul 23 '05 #1
18 3539
> I realise that I probably *should* be using C++ String types to store
my message. I know that I can allocate a char* to a String variable but
does it work the other way round? Can I pass a String to a function
expecting a char*


Use string's cstr method to get the C char* from a string object.
Sorry I am answering one of your questions. I am not sure of the other
answers myself.

Srini

Jul 23 '05 #2


st*********@hotmail.com wrote:
Hi,

I wonder if anyone could point me in the direction of a discussion on
the similarities and differences between the C++ String type and char*
strings?

The reason I ask is because I am working on a legacy application using
the old C socket.h library. The send function accepts the message to be
sent as a char*.

I am having problems making a deep copy of a char* string in C++.

Consider the following code sample:

class Message {

public:

Message () : unsent(NULL) {
};

void Add(char*); void Add(const char *); // would be better. void Del();
char* GetMsg(); const char* GetMsg(); // would be better, to prevent modifying msg
//outside this class void ShiftMsg(int);

~Message() {
Del();
}

private:

char* wholeMessage;
char* unsentBytes;

};

//Create deep copy of inmessage
void Message::Add (char* inmessage) {

wholeMessage = new char[strlen(inmessage) + 1]; inmessage need to be checked whether it's NULL or not.
Because strlen doesn't check. and it would crash if inmessage is NULL.
strcpy(wholeMessage,inmessage);

unsentBytes = wholeMessage;

}

//Release memory allocated to wholeMessage
void Message::Del() {

if (wholeMessage != NULL) {
delete [] wholeMessage;
}
unsentBytes = NULL;

}

//Get unsent portion of message
char* Message::GetUnsent() {

if (unsentBytes == NULL) {
return "";
}
else {
return unsentBytes;
}
}

//Increment unsentBytes pointer to point at unsent portion of
//message
void Message::ShiftMsg(int bytesSent) {
unsentBytes = unsentBytes + bytesSent;
}
I have a problem. When I attempt to allocate the momory for
wholeMessage using the new operator I get an access violation yet I do
not understand why. Can anyone explain what I am doing wrong?

I realise that I probably *should* be using C++ String types to store
my message. I know that I can allocate a char* to a String variable but
does it work the other way round? Can I pass a String to a function
expecting a char*

Finally, a question about general style. I feel I should be creating a
new instance of Message for each string I am processing and destroying
it once sent but this would involve me creating and destroying hundreds
of instances a second. Is there a large overhead involved in doing
this?

Many thanks for any help.

Lawrie.


Jul 23 '05 #3
Ian
st*********@hotmail.com wrote:

I have a problem. When I attempt to allocate the momory for
wholeMessage using the new operator I get an access violation yet I do
not understand why. Can anyone explain what I am doing wrong?
Is inmessage NULL terminated?
I realise that I probably *should* be using C++ String types to store
my message. I know that I can allocate a char* to a String variable but
does it work the other way round? Can I pass a String to a function
expecting a char*
string.c_str() does this.
Finally, a question about general style. I feel I should be creating a
new instance of Message for each string I am processing and destroying
it once sent but this would involve me creating and destroying hundreds
of instances a second. Is there a large overhead involved in doing
this?

There will be an overhead, it's up to you to decide if it is too high.
Try the most simple thing that will work, optimise if you have to.

Ian
Jul 23 '05 #4
The add method crashes with an access violation if inmessage is not
NULL.

The line

wholeMessage = new char[strlen(inmessage) + 1];

seems to cause the problem but I don't understand why I am getting an
access violation.

Jul 23 '05 #5
I believe inmessage is null terminated but even if it is not should
this cause a problem?

my new statement allocates a char array 1 byte bigger than the value
returned by strlen so there is enough space for the null termination
character.

Jul 23 '05 #6
st*********@hotmail.com wrote:
The add method crashes with an access violation if inmessage is not
NULL.

The line

wholeMessage = new char[strlen(inmessage) + 1];

seems to cause the problem but I don't understand why I am getting an
access violation.


Is inmessage a valid C style string, i.e. is it terminated with a '\0'
character?

Jul 23 '05 #7
On examination it would appear that inmessage is NOT '\0' terminated.

I don't understand why this is causing a problem when I allocate memory
though.

Jul 23 '05 #8


st*********@hotmail.com wrote:
I believe inmessage is null terminated but even if it is not should
this cause a problem?

my new statement allocates a char array 1 byte bigger than the value
returned by strlen so there is enough space for the null termination
character.


Could you show us a callstack?

Jul 23 '05 #9
<st*********@hotmail.com> wrote in message
news:11**********************@g47g2000cwa.googlegr oups.com...
On examination it would appear that inmessage is NOT '\0' terminated.

I don't understand why this is causing a problem when I allocate
memory
though.

strlen determines the length by looking for the 0-char. You do not
get the access violation because you allocate memory. You get it,
because you pass a non-0-terminated char array, which, if you read the
documentation, is not what strlen expects.

hth
--
jb

(reply address in rot13, unscramble first)
Jul 23 '05 #10
I have added a few lines of debug, checked the String inmessage for
'\o' chars and output the length returned by strlen BEFORE attempting
to allocate memory.

inmessage IS null terminated and strlen returns a valid length.

I am still at a loss to determine why I am getting the access violation.

Jul 23 '05 #11
Please disregard the previous post.

The char* inmessage is definately null terminated.

In a debug example strlen returns 71.

I therefore allocate a new char[72] which is big enough for the string
plus the /0 char.

I cannot understand how this is causing the access violation.

Jul 23 '05 #12
Okay, I have been experimenting with my code and have changed the ADD
method as follows:

void Message::Add (const char* inMessage) {

STD_TRY()

if (strchr(inMessage,'\0') != NULL) {
cout << "NULL TERMINATED\n";
}

cout << "strlen: " << strlen(inMessage) << "\n";
cout << "sizeof: " << sizeof inMessage << "\n";

if (inMessage != NULL) {
cout << "allocating\n";
wholeMessage = new char[10];
cout << "Allocated\n";
// wholeMessage = new char[strlen(inMessage) + 2];
// strcpy(wholeMessage,inMessage);
}
else {
wholeMessage = "";
cout << "Message::Add, NULL char* received\n";
}

unsentBytes = wholeMessage;

STD_CATCH("Message::Add")

} //Message::Add

Where STD_TRY() and STD_CATCH() are used to catch any exceptions.
Here is the output:

NULL TERMINATED
strlen: 71
sizeof: 4
allocating
Error in method: Message::Add
%SYSTEM-F-ACCVIO, access violation [blah blah blah]

As you can see I am simply trying to allocate a fixed size block of
memory without any calls to strlen() or strcpy() and I am still getting
an access violation.

Jul 23 '05 #13
st*********@hotmail.com writes:
if (strchr(inMessage,'\0') != NULL) {
cout << "NULL TERMINATED\n";
} Is this worth doing? In what circumstances do you think
"NULL TERMINATED\n" wouldn't be printed out?

As you can see I am simply trying to allocate a fixed size block of
memory without any calls to strlen() or strcpy() and I am still getting
an access violation.

This may be because of some earlier memory allocation problem. Something
like http://valgrind.org/ may be of use.

Jul 23 '05 #14
st*********@hotmail.com wrote:

class Message {
public:
Message () : unsent(NULL) { };
void Add(char*);
void Del();
char* GetMsg();
void ShiftMsg(int);

~Message() {
Del();
}
private:
char* wholeMessage;
char* unsentBytes;
};

//Create deep copy of inmessage
void Message::Add (char* inmessage) {
wholeMessage = new char[strlen(inmessage) + 1];
strcpy(wholeMessage,inmessage);
unsentBytes = wholeMessage;
}

I have a problem. When I attempt to allocate the momory for
wholeMessage using the new operator I get an access violation
yet I do not understand why. Can anyone explain what I am doing wrong?


Probably you have already corrupted the heap earlier in
the program. For example, Message's constructor does not set
wholeMessage to anything, and you don't have a valid
copy constructor or assignment operator.

Can you post a COMPLETE program that causes the crash?

Jul 23 '05 #15
st*********@hotmail.com wrote:
Hi,

I wonder if anyone could point me in the direction of a discussion on
the similarities and differences between the C++ String type and char*
strings?
I can give you it in one word. Char* is NOT a string type. It's a
pointer to a single character. You need to convey other information
to use it as a pseudo-string type. You're responsible for allocating,
deallocation, copying, remembering the size, etc... separately from
just remembering where the first byte of the string is.

I have a problem. When I attempt to allocate the momory for
wholeMessage using the new operator I get an access violation yet I do
not understand why. Can anyone explain what I am doing wrong?
Your first problem is your class doesn't have a copy constructor or
copy assignment operator. Further, you don't initialize the two
pointers which means that your destructor does the wrong thing
(by the way delete of a null pointer is a no op, so your test
in Del is unnecessary).

You don't show how it is used, but are you sure inmessage is a null
terminated string as wella s not being a NULL pointer?

I realise that I probably *should* be using C++ String types to store
my message. I know that I can allocate a char* to a String variable but
does it work the other way round? Can I pass a String to a function
expecting a char*
Bingo. There is a function called c_str() as a member of std::string
that returns a const char*. If you need a non-const string, then you
will have to copy (although you might do the following):

std::string string = "yada yada yada";
const char* csp = string.c_str(); // ok, we have a const char*
// now make it writable.
std::vector<char> cv(csp, csp+string.size()+1);
function_requiring_charptr(&csp[0]);

Finally, a question about general style. I feel I should be creating a
new instance of Message for each string I am processing and destroying
it once sent but this would involve me creating and destroying hundreds
of instances a second. Is there a large overhead involved in doing
this?


You can add add a "Clear" function to your code that rather resets the
string rather than freeing memory.
Jul 23 '05 #16
st*********@hotmail.com wrote:
if (strchr(inMessage,'\0') != NULL) {
cout << "NULL TERMINATED\n";
}


Remember what a char* is. It is just an address. You're imagining that
the memory is full of "objects". It's not, when you're dealing with it
at this level; it's just full of bytes. If inMessage is not null
terminated, strchr will just keep stepping through memory until it finds
a 0 (and they are quite common).

The code you have posted has all looked reasonable, though as others
have pointed out you could add a fews consts and so on. The bug in your
program is not in the code that you've posted. You'll need to post a
complete example that we can run and see the error. In the process of
creating a simple example you'll probably find the error yourself.

You might also like to try something like Purify or Valgrind.

--Phil.
Jul 23 '05 #17
Le mercredi 8 juin 2005 à 13:51, st*********@hotmail.com a écrit dans
comp.lang.c++*:
I have added a few lines of debug, checked the String inmessage for
'\o' chars and output the length returned by strlen BEFORE attempting
to allocate memory.

inmessage IS null terminated and strlen returns a valid length.

I am still at a loss to determine why I am getting the access violation.


From my experience, when a reasonable allocation attempt fails with an
access violation, it means that memory was corrupted at some point
before the allocation attempt; by writing outside the valid boundaries
of another memory block, you probably overwrote the data used by the
allocator to link memory blocks together and keep track of available
blocks.

Good luck.

--
___________ 08/06/2005 16:01:08
_/ _ \_`_`_`_) Serge PACCALIN -- sp ad mailclub.net
\ \_L_) Il faut donc que les hommes commencent
-'(__) par n'être pas fanatiques pour mériter
_/___(_) la tolérance. -- Voltaire, 1763
Jul 23 '05 #18
st*********@hotmail.com wrote in news:1118236177.754102.167320
@g49g2000cwa.googlegroups.com:
Okay, I have been experimenting with my code and have changed the ADD
method as follows:

void Message::Add (const char* inMessage) {

STD_TRY()

if (strchr(inMessage,'\0') != NULL) {
cout << "NULL TERMINATED\n";
}

cout << "strlen: " << strlen(inMessage) << "\n";
cout << "sizeof: " << sizeof inMessage << "\n";

if (inMessage != NULL) {
cout << "allocating\n";
wholeMessage = new char[10];
cout << "Allocated\n";
// wholeMessage = new char[strlen(inMessage) + 2];
// strcpy(wholeMessage,inMessage);
}
else {
wholeMessage = "";
cout << "Message::Add, NULL char* received\n";


Uh oh.... does your delete code take this case into account? If you try to
delete[] wholeMessage after this, game over. Anything can happen.

[snip]
Jul 23 '05 #19

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

Similar topics

9
by: Colin Doig | last post by:
Hi, I need to pass an array of strings to a function, but I can't get it to work. This is what I wrote : #include <stdio.h> void a_function(char *blah) { printf("%s %s %s", blah, blah,...
4
by: John | last post by:
I'm trying (struggling) to use realloc to grow a list of strings. The number of strings is not known (this is a subset of an assignment to write a recursive ls program... my BS was in EE, so I'm...
7
by: Roman Mashak | last post by:
Hello, All! I wonder is it possible to define an array containing strings, not single characters? What I want is array 'table' that will have N elements, and every element is a strings tailoring...
9
by: Steven | last post by:
Hello, I have a question about strcmp(). I have four words, who need to be compared if it were two strings. I tried adding the comparison values like '(strcmp(w1, w2) + strcmp(w3, w4))', where...
21
by: c | last post by:
Hi everybody. I'm working on converting a program wriiten on perl to C, and facing a problem with concatenate strings. Now here is a small program that descripe the problem, if you help me to...
23
by: arnuld | last post by:
i was doing exercise 4.3.1 - 4.29 of "C++ Primer 4/e" where authors, with "run-time shown", claim that C++ Library strings are faster than C-style character strings. i wrote the same programme in...
3
by: sunilkjin | last post by:
Hi , I am trying to alllocate a 2D array of strings and returning it to a functiion, I get a memory access error. What is wrong with the program? int main3DArray( char *** x); int main() {...
28
by: hlubenow | last post by:
Hello, I really like Perl and Python for their flexible lists like @a (Perl) and a (Python), where you can easily store lots of strings or even a whole text-file. Now I'm not a...
95
by: hstagni | last post by:
Where can I find a library to created text-based windows applications? Im looking for a library that can make windows and buttons inside console.. Many old apps were make like this, i guess ...
19
by: bowlderyu | last post by:
Hello, all. If a struct contains a character strings, there are two methods to define the struct, one by character array, another by character pointer. E.g, //Program for struct includeing...
0
by: taylorcarr | last post by:
A Canon printer is a smart device known for being advanced, efficient, and reliable. It is designed for home, office, and hybrid workspace use and can also be used for a variety of purposes. However,...
0
by: aa123db | last post by:
Variable and constants Use var or let for variables and const fror constants. Var foo ='bar'; Let foo ='bar';const baz ='bar'; Functions function $name$ ($parameters$) { } ...
0
by: ryjfgjl | last post by:
In our work, we often receive Excel tables with data in the same format. If we want to analyze these data, it can be difficult to analyze them because the data is spread across multiple Excel files...
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
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
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,...

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.