|
|||||
|
|
#1 |
|
|
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� --- |
|
|
#2 |
|
|
"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 |
|
|
#3 |
|
|
> 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/ |
|
|
#4 |
|
|
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 |
|
|
#5 |
|
|
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/ |
|
|
#6 |
|
|
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! |
|
|
#7 |
|
|
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 |
|
|
#8 |
|
|
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 |
|
|
#9 |
|
|
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 |
|
|
#10 |
|
|
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/ |