> Programming Languages > C
Various Topics Home | Disclaimer | Report Adult Posts

Various Topics on C



C - "simple malloc() problem" in Programming Languages


Old 06-21-2004   #1
..rmit_crab..
 
Default simple malloc() problem

Can someone explain to a C newbie why this doesn't work as I expect it
to work? (expectations clearly outlined in the printf statement in
main routine)

OS: Linux 2.4.26
GCC: 2.95.4

void modify_pointer(char *);

int main(int argc, char *argv[]) {
char *ptr_to_string;
modify_pointer(ptr_to_string);
printf("but why doesn't this say hello? %s\n", ptr_to_string);
}

void modify_pointer(char *the_ptr) {
the_ptr = (char *) malloc(strlen("hello"));
strcpy(the_ptr, "hello");
printf("this says hello: %s\n", the_ptr);
}

--
output:

this says hello: hello
but why doesn't this say hello? p�

---
 
Old 06-21-2004   #2
..j.. ..m.. .. ..nv..
 
Default Re: simple malloc() problem


"hermit_crab67" <hermit_crab67@yahoo.com> wrote in message news:520b1280.0406202300.3e7c10da@posting.google.c om...
> Can someone explain to a C newbie why this doesn't work as I expect it
> to work? (expectations clearly outlined in the printf statement in
> main routine)
>


The problem isn't with the malloc (except the memory leakage here).
ptr_to_string has been p***ed by value, so the ***igment

the_ptr = (char *) malloc(strlen("hello")); /* don't cast */

is local to the modify_pointer(). Do as follows:


> OS: Linux 2.4.26
> GCC: 2.95.4
>
> void modify_pointer(char *);


void modify_pointer(char **);
>
> int main(int argc, char *argv[]) {
> char *ptr_to_string;
> modify_pointer(ptr_to_string);


modify_pointer(&ptr_to_string);

> printf("but why doesn't this say hello? %s\n", ptr_to_string);
> }
>
> void modify_pointer(char *the_ptr) {
> the_ptr = (char *) malloc(strlen("hello"));
> strcpy(the_ptr, "hello");
> printf("this says hello: %s\n", the_ptr);
> }


void modify_pointer(char **the_ptr) {
*the_ptr = malloc(sizeof("hello"));
strcpy(*the_ptr, "hello");
printf("this says hello: %s\n", *the_ptr);
}

This might be of some help:

In C, the only true method of parameter p***ing is known as "call by value".
The following example demonstrates the last statement:

#include <stdlib.h>

void
raisin ( float x ) { /* process x here */ }

void
grape ( float *xp ) { /* process xp here */ }

int
main ( void )
{
float f;
float *fp = &f;

/* ... */
raisin ( f );
grape ( fp );
return EXIT_SUCCESS;
}

When the declaration of an argument (f and fp) matches with the declaration
of the corresponding parameter (x and xp), then the argument has been p***ed by
value. And, when an argument is p***ed by value, any modification the called-
function makes to the parameter does not reflect in the calling-function. So,
any modification to xp does not reflect in fp, however, any modification to *xp
reflects in f.

--
Vijay Kumar R Zanvar
Pointers and Arrays - http://www.geocities.com/vijoeyz/art...dex.html#seq21


 
Old 06-21-2004   #3
..manu.. ..laha..
 
Default Re: simple malloc() problem

In 'comp.lang.c', hermit_crab67@yahoo.com (hermit_crab67) wrote:

> Can someone explain to a C newbie why this doesn't work as I expect it
> to work? (expectations clearly outlined in the printf statement in
> main routine)
>
> OS: Linux 2.4.26
> GCC: 2.95.4
>
> void modify_pointer(char *);


Starts badly. If you want to modify an object, you must p*** the address of
it. Remember, in C, only the values are p***ed.

void modify_pointer(char **pp);

Your problem is covered by the FAQ:

http://www.eskimo.com/~scs/C-faq/q4.8.html

> int main(int argc, char *argv[]) {
> char *ptr_to_string;


This pointer is uninitialized.

> modify_pointer(ptr_to_string);


P***ing an uninitialized value to a function invokes an undefined behaviour.
Anything can happen. A decent and well-configured compiler should have warned
you about that.

Because you are using gcc (note: gcc is not GCC), I suggest you add this to
your command line:

-W -Wall -O2

and the following in addition if you want to comply to the C standard:

-ansi -pedantic

> printf("but why doesn't this say hello? %s\n", ptr_to_string);


Be sure that <stdio.h> is included. printf() needs a prototype. It's
mandatory.

> }
>
> void modify_pointer(char *the_ptr) {
> the_ptr = (char *) malloc(strlen("hello"));


Modifiying the value of a parameter is often the indication of a bad design.

No need for the cast. Be sure that you have included <stdlib.h>. malloc() can
fail. You must test the returned value against NULL.

strlen() wants <string.h>. It returns the length of the string, not it's
size. You're off by one.

char * the_ptr = malloc(strlen("hello") + 1);

or, in this special case involving a string literal:

char * the_ptr = malloc(sizeof "hello");

> strcpy(the_ptr, "hello");


But it is recommended to avoid such repetitions.
- Not all compilers are smart enough to merge similar string literals, hence
a waste of space.
- It makes maintenance a hell

I recommend an initialized array of const char:

char const s[] = "hello";
char * the_ptr = malloc(strlen(S) + 1);

if (the_ptr != NULL)
{
strcpy(the_ptr, S);
<...>
}

> printf("this says hello: %s\n", the_ptr);
> }


Not to mention that the value of 'the_ptr' must now be returned via the new
char ** pp parameter (after having checked that pp is not NULL, of course).

if (pp != NULL)
{
*pp = the_ptr;
}

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
 
Old 06-21-2004   #4
....
 
Default Re: [OT] simple malloc() problem

Emmanuel Delahaye wrote:
> Modifiying the value of a parameter is often the indication of a bad design.


I'm interested in your thoughts behind this statement.

Case

 
Old 06-21-2004   #5
..manu.. ..laha..
 
Default Re: [OT] simple malloc() problem

In 'comp.lang.c', Case <no@no.no> wrote:

>> Modifiying the value of a parameter is often the indication of a bad
>> design.

>
> I'm interested in your thoughts behind this statement.


The code given by the original poster is a perfect illustration of this
statement.

Apart for micro-optimisation purpose, there is not good reasons for a
parameter to have its value changed. This is the reason why, at a first
glance, I recommend to define the parameters with const. If it clashes
somewhere, it means that it's time to think harder about the design.

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
 
Old 06-21-2004   #6
..Falcon..
 
Default Re: [OT] simple malloc() problem

Case wrote:
> Emmanuel Delahaye wrote:
>
>> Modifiying the value of a parameter is often the indication of
>> a bad design.

>
> I'm interested in your thoughts behind this statement.


This is a religious issue, on which E.D. and I disagree. I treat
parameters as externally initialized local variables (which they
are). If a function is so long that I can't easily spot the need
for the original value, then there is a design problem and the
function needs to be broken up into smaller and simpler functions.

--
Chuck F (cbfalconer@yahoo.com) (cbfalconer@worldnet.att.net)
Available for consulting/temporary embedded and systems.
<http://cbfalconer.home.att.net> USE worldnet address!


 
Old 06-21-2004   #7
..n ..p
 
Default Re: [OT] simple malloc() problem

In <Xns950F73236E5Fhsnoservernet@212.27.42.74> Emmanuel Delahaye <emdelYOURBRA@noos.fr> writes:

>In 'comp.lang.c', Case <no@no.no> wrote:
>
>>> Modifiying the value of a parameter is often the indication of a bad
>>> design.

>>
>> I'm interested in your thoughts behind this statement.


Like most such statements made by Emmanuel, it's a matter of pure
religion taken as fact.

>The code given by the original poster is a perfect illustration of this
>statement.


And the following code is a perfect rebuttal of the same statement:

#include <stdio.h>

int main(int argc, char **argv)
{
while (argc-- > 0) puts(*argv++);
return 0;
}

At the end of the loop, the initial values of argc and argv are
entirely irrelevant, so there is no *good* (i.e. non-religious) reason
for preserving them.

And although this is a trivial example, it is typical for code parsing
its command line arguments. See also the example at page 117 in K&R2.

Dan
--
Dan Pop
DESY Zeuthen, RZ group
Email: Dan.Pop@ifh.de
 
Old 06-21-2004   #8
..r.. ..rinki.. ..ff.. .. ..e ..¬ƒceâ€..
 
Default Re: [OT] simple malloc() problem

Dan Pop wrote:
> In <Xns950F73236E5Fhsnoservernet@212.27.42.74> Emmanuel Delahaye <emdelYOURBRA@noos.fr> writes:
>
>> In 'comp.lang.c', Case <no@no.no> wrote:
>>
>>>> Modifiying the value of a parameter is often the indication of a bad
>>>> design.
>>>
>>> I'm interested in your thoughts behind this statement.

>
> Like most such statements made by Emmanuel, it's a matter of pure
> religion taken as fact.
>
>> The code given by the original poster is a perfect illustration of this
>> statement.

>
> And the following code is a perfect rebuttal of the same statement:
>
> #include <stdio.h>
>
> int main(int argc, char **argv)
> {
> while (argc-- > 0) puts(*argv++);
> return 0;
> }
>
> At the end of the loop, the initial values of argc and argv are
> entirely irrelevant, so there is no *good* (i.e. non-religious) reason
> for preserving them.


Appreciated.

- Dario
 
Old 06-21-2004   #9
..o.. .. ..las..
 
Default Re: [OT] simple malloc() problem

Dan Pop <Dan.Pop@cern.ch> scribbled the following:
> In <Xns950F73236E5Fhsnoservernet@212.27.42.74> Emmanuel Delahaye <emdelYOURBRA@noos.fr> writes:
>>In 'comp.lang.c', Case <no@no.no> wrote:
>>>> Modifiying the value of a parameter is often the indication of a bad
>>>> design.
>>>
>>> I'm interested in your thoughts behind this statement.


> Like most such statements made by Emmanuel, it's a matter of pure
> religion taken as fact.


As it stands, I happen to agree with him. Emphasis on "often the
indication of" bit. There are legitimate causes for modifying the value
of a parameter but usually it's a sign of the programmer not
understanding how C's parameter p***ing works.

--
/-- Joona Palaste (palaste@cc.helsinki.fi) ------------- Finland --------\
\-- http://www.helsinki.fi/~palaste --------------------- rules! --------/
"There's no business like slow business."
- Tailgunner
 
Old 06-21-2004   #10
..manu.. ..laha..
 
Default Re: [OT] simple malloc() problem

In 'comp.lang.c', Dan.Pop@cern.ch (Dan Pop) wrote:

> Like most such statements made by Emmanuel, it's a matter of pure
> religion taken as fact.


I was naively thinking that Usenet was not the place for nominative attacks.
Sounds that I was wrong. My statements belong to my coding guidelines that
result from a rather long experience in C-programming. You may gently agree
or not, byt why being so harsh ?

>>The code given by the original poster is a perfect illustration of this
>>statement.

>
> And the following code is a perfect rebuttal of the same statement:
>
> #include <stdio.h>
>
> int main(int argc, char **argv)
> {
> while (argc-- > 0) puts(*argv++);
> return 0;
> }
>
> At the end of the loop, the initial values of argc and argv are
> entirely irrelevant, so there is no *good* (i.e. non-religious) reason
> for preserving them.


What a strange example. What if I now want to access to the arguments ? Or to
check the number of arguments?

Your example illustrates exactly what I try to fight against : the
destruction of the initial value of a parameter.

> And although this is a trivial example, it is typical for code parsing
> its command line arguments. See also the example at page 117 in K&R2.


I think that I'm not the one that consider the K&R2 a Sacred Book. Who is the
one with a religious attitude ?

--
-ed- get my email here: http://marreduspam.com/ad672570
The C-language FAQ: http://www.eskimo.com/~scs/C-faq/top.html
C-reference: http://www.dinkumware.com/manuals/reader.aspx?lib=c99
FAQ de f.c.l.c : http://www.isty-info.uvsq.fr/~rumeau/fclc/
 

Thread Tools
Display Modes





Powered by vBulletin®
Copyright ©2000 - 2009, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0