473,387 Members | 3,821 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,387 software developers and data experts.

Ok, I was in error (or my foot still doesn't taste so great)

I recently replied to MC felons post on returning strings and was in error
on what I was trying to do. After running completely thru my code, I did
find that I was misunderstanding how C++ works with char arrays. After much
testing, I would like to submit the following code for comments:

#include <Stdlib.h>

char *Func1()
/*-------------------------------------------------------------------
allocates memory and fills it with the string, "Hello World!" and
passes ownership to the calling function
---------------------------------------------------------------------*/
{
char *tmp = (char*)malloc(20); // allocate space for the array
char T2[20] = "Hello World!";
int i = 0;

// fill the char array
do
{
tmp[i] = T2[i];
i++;
}while(T2[i] != 0);
tmp[i] = 0;
return tmp;
};

//---------------------------------------------------------------
void Func2(char *tmp)
/*--------------------------------------------------------------
Takes a string argument by reference and changes it to
"Not Hello World"
---------------------------------------------------------------*/
{
char* T2 = "Not Hello World\0";

int i=0;
do
{
tmp[i] = T2[i];
i++;
}while(T2[i]!=0);
tmp[i]=0;
};

//---------------------------------------------------------------
int main()
{
char *Tmp = Func1(); // allocates memory for array and fills it with "Hello
World"
Func2(Tmp); // change string to "Not Hello World!"
free(Tmp); // free memory allocated in Func1 and assigned
to Tmp;
};

In all my test runs, I get the desired results without any errors. While I
acknowledge that using the string functions would be preferable, I still
like to code my own solutions sometimes just for the learning experience.
Dec 13 '06 #1
15 1313
David Pratt wrote:
I recently replied to MC felons post on returning strings and was in
error
on what I was trying to do. After running completely thru my code, I did
find that I was misunderstanding how C++ works with char arrays. After
much testing, I would like to submit the following code for comments:
I sure looks like C to me.
#include <Stdlib.h>

//---------------------------------------------------------------
int main()
{
char *Tmp = Func1(); // allocates memory for array and fills it with
"Hello World"
Func2(Tmp); // change string to "Not Hello World!"
free(Tmp); // free memory allocated in Func1 and
assigned
to Tmp;
};

In all my test runs, I get the desired results without any errors. While I
acknowledge that using the string functions would be preferable, I still
like to code my own solutions sometimes just for the learning experience.
Why not and have a look at the GNU implementation of <string.h>?

BTW, there were two primary reasons I didn't like C. One was malloc, and
the other was free.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 13 '06 #2

David Pratt wrote:
I recently replied to MC felons post on returning strings and was in error
on what I was trying to do. After running completely thru my code, I did
find that I was misunderstanding how C++ works with char arrays. After much
testing, I would like to submit the following code for comments:

#include <Stdlib.h>

char *Func1()
/*-------------------------------------------------------------------
allocates memory and fills it with the string, "Hello World!" and
passes ownership to the calling function
---------------------------------------------------------------------*/
{
char *tmp = (char*)malloc(20); // allocate space for the array
char T2[20] = "Hello World!";
int i = 0;

// fill the char array
do
{
tmp[i] = T2[i];
i++;
}while(T2[i] != 0);
tmp[i] = 0;
Why reinvent the wheel? You could have just done this whole loop with
strcpy and it's all a whole lot more work than using std::string.

Dec 13 '06 #3

"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@16g2000cwy.googlegrou ps.com...
Why reinvent the wheel? You could have just done this whole loop with
strcpy and it's all a whole lot more work than using std::string.
Ah but if I had done that, I would still be operating under false
assumptions about the way C++ handles pointers. Now I KNOW better. What can
I say? I was an engineering student in college, and I have this ever present
itch to try and figure out how things work, especially when what I thought
would work doesn't. I learned a lot over the past couple of days about C++
basics. And trying to reinvent the wheel got us tracked vehicles.

"Sometimes learning what you don't know that you don't know can be more
important than learning about what you know that you don't know." Wener
Earhart, founder of est.
Dec 13 '06 #4

David Pratt skrev:
"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@16g2000cwy.googlegrou ps.com...
Why reinvent the wheel? You could have just done this whole loop with
strcpy and it's all a whole lot more work than using std::string.
Ah but if I had done that, I would still be operating under false
assumptions about the way C++ handles pointers. Now I KNOW better. What can
I say? I was an engineering student in college, and I have this ever present
itch to try and figure out how things work, especially when what I thought
would work doesn't. I learned a lot over the past couple of days about C++
basics. And trying to reinvent the wheel got us tracked vehicles.
This is just perfectly fine. Now go forget all that knowledge and start
using std::string instead. I believe you realise that while your code
did work well in your test, simple changes could have changed that
(e.g. mallocing somewhat less than 20 bytes.
std::string should be preferred at all times unless you have very good
argument to use something different.

/Peter
>
"Sometimes learning what you don't know that you don't know can be more
important than learning about what you know that you don't know." Wener
Earhart, founder of est.
Dec 13 '06 #5

David Pratt wrote:
"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@16g2000cwy.googlegrou ps.com...
Why reinvent the wheel? You could have just done this whole loop with
strcpy and it's all a whole lot more work than using std::string.
Ah but if I had done that, I would still be operating under false
assumptions about the way C++ handles pointers. Now I KNOW better. What can
I say? I was an engineering student in college, and I have this ever present
itch to try and figure out how things work, especially when what I thought
would work doesn't. I learned a lot over the past couple of days about C++
basics. And trying to reinvent the wheel got us tracked vehicles.
FWIW I agree with you absolutely. (I would ignore all those other
miserable old people on this newsgroup and experiment). Bear in mind
though that the standard libraries are the result of a huge amount of
work, not only in the coding but also in the documentation, which means
that for serious work it is usually easier to use them. However its
only when you try to do it yourself that you appreciate that IMO. And
of course you may also come up with something better too someday..

regards
Andy Little

Dec 13 '06 #6

David Pratt wrote:
"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@16g2000cwy.googlegrou ps.com...
Why reinvent the wheel? You could have just done this whole loop with
strcpy and it's all a whole lot more work than using std::string.
Ah but if I had done that, I would still be operating under false
assumptions about the way C++ handles pointers.
Well, you learned how null terminated character strings work possibly.
It isn't quite the same thing.

Now I KNOW better. What can
I say? I was an engineering student in college, and I have this ever present
itch to try and figure out how things work, especially when what I thought
would work doesn't. I learned a lot over the past couple of days about C++
basics. And trying to reinvent the wheel got us tracked vehicles.
Well, here...something to digest then:

while (*ptr1++ = *ptr2++);

Dec 13 '06 #7

"David Pratt" <Pr********@sbcglobal.netwrote in message
news:_6*******************@newssvr14.news.prodigy. net...
I recently replied to MC felons post on returning strings and was in error
on what I was trying to do. After running completely thru my code, I did
find that I was misunderstanding how C++ works with char arrays. After
much testing, I would like to submit the following code for comments:
(Ok. I'll avoid the obvious comments about using std::string, since you're
interested in arrays only here.)
#include <Stdlib.h>

char *Func1()
/*-------------------------------------------------------------------
allocates memory and fills it with the string, "Hello World!" and
passes ownership to the calling function
---------------------------------------------------------------------*/
{
char *tmp = (char*)malloc(20); // allocate space for the array
Why malloc? Why not new[]?
char T2[20] = "Hello World!";
You're making the array of size 20 because Func2 is going to add data to it.
It's bad design to specify a value in one function that's only needed by
some other function. If you've got a "global" requirement like this, it's
better to put the value (20) in a global constant, and use that constant
when allocating.
int i = 0;

// fill the char array
do
{
tmp[i] = T2[i];
i++;
}while(T2[i] != 0);
tmp[i] = 0;
return tmp;
};

//---------------------------------------------------------------
void Func2(char *tmp)
/*--------------------------------------------------------------
Takes a string argument by reference and changes it to
That's not "by reference". By reference means using &. You're passing via
a pointer.
"Not Hello World"
---------------------------------------------------------------*/
{
char* T2 = "Not Hello World\0";

int i=0;
do
{
tmp[i] = T2[i];
i++;
}while(T2[i]!=0);
What if T2[0]==0? Better to use a for loop here.
tmp[i]=0;
};
There is nothing in that function which tells you if it's safe to write to a
given location in the array. It's got no way to know that in some other
function (Func1), this pointer was allocated as an array of 20 chars. What
if you change Func1 to allocate only 12 chars?

Using this design, it would be much better if you added another parameter to
Func2 which would tell it how big the array is, so you could stop writing
before you got to its end. Or, if you followed my earlier advice and put
the value 20 into a global constant, you could use that as a safety check.
//---------------------------------------------------------------
int main()
{
char *Tmp = Func1(); // allocates memory for array and fills it with
"Hello World"
Func2(Tmp); // change string to "Not Hello World!"
free(Tmp); // free memory allocated in Func1 and
assigned
Better to use new[] and delete[] in C++, especially if you decide to extend
this type of code to an array of objects. Using new[] and delete[], the
constructors and destructors for those objects will be called. Not so for
malloc/free.
to Tmp;
};

In all my test runs, I get the desired results without any errors. While I
acknowledge that using the string functions would be preferable, I still
like to code my own solutions sometimes just for the learning experience.
Me, too. Now you just need to follow the advice given. ;-)

-Howard
Dec 13 '06 #8
Howard wrote:
"David Pratt" <Pr********@sbcglobal.netwrote:
void Func2(char *tmp)
/*--------------------------------------------------------------
Takes a string argument by reference and changes it to

That's not "by reference". By reference means using &. You're passing via
a pointer.
"By reference" means that the function refers to a value that
exists outside of it. There are two ways to do this in C++:
pointers and references.

Dec 14 '06 #9
* Old Wolf:
Howard wrote:
>"David Pratt" <Pr********@sbcglobal.netwrote:
>>void Func2(char *tmp)
/*--------------------------------------------------------------
Takes a string argument by reference and changes it to
That's not "by reference". By reference means using &. You're passing via
a pointer.

"By reference" means that the function refers to a value that
exists outside of it. There are two ways to do this in C++:
pointers and references.
In a sense you're right. A design model with some argument passed by
reference, might be implemented in C++ as a C++ alias, a pointer, or
even an array index. But in the context of the C++ language "pass by
reference" means &: all else is pass by value.

--
A: Because it messes up the order in which people normally read text.
Q: Why is it such a bad thing?
A: Top-posting.
Q: What is the most annoying thing on usenet and in e-mail?
Dec 14 '06 #10
>
Well, here...something to digest then:

while (*ptr1++ = *ptr2++);
I am assuming that ptr1 and ptr are both char Array pointers.

Well, I do not know if it's just my compiler or what, but the assembly code
generated by the above code will allways evaluate true, resulting in an
endless loop that overwrites all the memory after ptr2 with the contents
after ptr1. But might you mean:
while(*ptr1++ == *ptr2++);
If so then you have undeterminate results if both arrays are equal strings
because the bytes past the end of the arrays are not guaranteed to be
unequal. The expression might or might not evaluate to false after the ends
of each array are reached.
Dec 14 '06 #11
David Pratt wrote:
>>
Well, here...something to digest then:

while (*ptr1++ = *ptr2++);
I am assuming that ptr1 and ptr are both char Array pointers.

Well, I do not know if it's just my compiler or what, but the assembly
code generated by the above code will allways evaluate true, resulting in
an endless loop that overwrites all the memory after ptr2 with the
contents
after ptr1. But might you mean:
while(*ptr1++ == *ptr2++);
If so then you have undeterminate results if both arrays are equal
strings
because the bytes past the end of the arrays are not guaranteed to be
unequal. The expression might or might not evaluate to false after the
ends of each array are reached.
if ptr2 is a NTBS, *ptr1++ = *ptr2++ should get to *ptr2=='\0'. That should
terminate the loop because you are assigning *ptr1='\0' which
returns '\0', and should evaluate to false.
This is verbatim from pg 106 of K&R.
<quote>
void strcpy(char *s, char *t)
{
while(*s++ = *t++)
;
}
Although this may seem cryptic at first sight, the notational convenience is
considerable, and the idiom should be mastered, because you will see it
frequently in C programs.
</quote>
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 14 '06 #12
Alf P. Steinbach wrote:
* Old Wolf:
>Howard wrote:
>>"David Pratt" <Pr********@sbcglobal.netwrote:
void Func2(char *tmp)
/*--------------------------------------------------------------
Takes a string argument by reference and changes it to
That's not "by reference". By reference means using &. You're passing
via a pointer.

"By reference" means that the function refers to a value that
exists outside of it. There are two ways to do this in C++:
pointers and references.

In a sense you're right. A design model with some argument passed by
reference, might be implemented in C++ as a C++ alias, a pointer, or
even an array index. But in the context of the C++ language "pass by
reference" means &: all else is pass by value.
http://www.parashift.com/c++-faq-lit...semantics.html

http://publib.boulder.ibm.com/infoce...ef/cplr233.htm

"Pass by reference

Passing by by reference refers to a method of passing the address of an
argument in the calling function to a corresponding parameter in the called
function. C onlyIn C, the corresponding parameter in the called function
must be declared as a pointer type. C++ only In C++, the corresponding
parameter can be declared as any reference type, not just a pointer type."
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 14 '06 #13
David Pratt schrieb:
"Noah Roberts" <ro**********@gmail.comwrote in message
news:11*********************@16g2000cwy.googlegrou ps.com...
Why reinvent the wheel? You could have just done this whole loop with
strcpy and it's all a whole lot more work than using std::string.
Ah but if I had done that, I would still be operating under false
assumptions about the way C++ handles pointers. Now I KNOW better. What can
I say? I was an engineering student in college, and I have this ever present
itch to try and figure out how things work, especially when what I thought
would work doesn't. I learned a lot over the past couple of days about C++
basics. And trying to reinvent the wheel got us tracked vehicles.

"Sometimes learning what you don't know that you don't know can be more
important than learning about what you know that you don't know." Wener
Earhart, founder of est.
Well, as it seems you like citations. Here is one, dedicated to you
personally.

"Sometimes it is good to read a book. You should read one book in your
life, better would be two or even three." F.J.K., wizard of Oz.

Honestly, if you are interested in a C-like programming style, read the
K.&.R. You'll be amazed at how much you can learn in how little time,
by listening to smart people. After all, you don't want to be cited by
your successors with:

"If I haven't seen further than others, it's because I refused standing
on the shoulders of giants and had to reinvent and refine strcpy all by
myself 'without cheating'." David Pratt, founder of nothing

Dec 14 '06 #14
F.J.K. wrote:
David Pratt schrieb:
Honestly, if you are interested in a C-like programming style, read the
K.&.R. You'll be amazed at how much you can learn in how little time,
by listening to smart people. After all, you don't want to be cited by
your successors with:
I'll refrain from the personal jabs. I do agree, however, that K&R seems
like a good source for David to consult. I keep pulling it off the shelf
wishing I had time to read it again myself.
--
NOUN:1. Money or property bequeathed to another by will. 2. Something handed
down from an ancestor or a predecessor or from the past: a legacy of
religious freedom. ETYMOLOGY: MidE legacie, office of a deputy, from OF,
from ML legatia, from L legare, to depute, bequeath. www.bartleby.com/61/
Dec 14 '06 #15

David Pratt wrote:

Well, here...something to digest then:

while (*ptr1++ = *ptr2++);
I am assuming that ptr1 and ptr are both char Array pointers.

Well, I do not know if it's just my compiler or what, but the assembly code
generated by the above code will allways evaluate true, resulting in an
endless loop that overwrites all the memory after ptr2 with the contents
after ptr1.
Examine the expression. The first thing to take place is the
incrementing of the pointers and the result of that is the original
value. Second is the dereference of the original value. Third the
value of the rvalue is assigned to the lvalue location. Finally the
data that was copied is the result of the expression. Assuming we have
a null terminated string the last data value of ptr2 will be a 0 and
thus ending the loop...after it is copied into ptr1.

It's strcpy.
But might you mean:
while(*ptr1++ == *ptr2++);
If so then you have undeterminate results if both arrays are equal strings
because the bytes past the end of the arrays are not guaranteed to be
unequal. The expression might or might not evaluate to false after the ends
of each array are reached.
Correct, that will not do the same thing as the result of == is either
true/false based on the sameness of l and r operands...'\0' won't
terminate the loop in this case.

Dec 14 '06 #16

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

Similar topics

4
by: Bradley Kite | last post by:
Hi all. I'm trying to diagnose/solve a problem with internet explorer, whereby sometimes the form submits, and other times IE produces an 'invalid syntax' error. First, I have a form, and...
2
by: RK | last post by:
Hi I am using the following code in the button_click event in xxxxx.htm page which is URL for the showModalDialog window. function btnAddComment_Onclick() { var user_info = new...
1
by: Lisa | last post by:
Can anyone help me with an "Automation Error" I am receiving in Access XP? I am using the Combo Box wizard to create a combo box on a simple form and receive the following error "Automation Error....
0
by: mikelca785 | last post by:
I am getting this error message when building my application. All of my source files compile without error, but when I try to build that's the error I get. I am not very familiar with using the...
6
by: dee | last post by:
Hi In web.config I have to the following: <configuration> <system.web> <customErrors defaultRedirect="error.htm" mode="On" /> </system.web> </configuration>
0
by: .Net Sports | last post by:
I'm trying to build a datagrid project in vs.net, and getting an error that doesnt make sense: \\\\\\\\\\\\\\ Could not load type 'SportsMProject.btresults2a'. Source Error: Line 1: <%@...
5
by: OHM | last post by:
Hi everyone, I have a problem with error handling and wondered if anyone has managed to implement a global exception handling model. Is it possible to ensure that you see all exceptions before...
1
by: dave_93_98 | last post by:
Hello, I am trying to use my apps global.asax and web.config to log an error message and move to a custom error page. This works great locally but does not work on a Win2K3 server (it redirects to...
25
by: dennijr | last post by:
ok, shell always used to be easy for me, now its starting to get annoying cause i dont know wats wrong heres the simplist code possible: Private Sub IExplorer_Click() a = Shell("C:\Program...
2
by: lisa007 | last post by:
Hi i'm trying to create a form wher user has a fields to enter password and then repeat password if password and repeat password doenst match echo error password doesnt match this is my password...
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: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
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: 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
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...

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.