function returning pointer

  • Follow


I don't understand the difference between the following:

void foo( char *s ) {
  s = malloc( 10 );
}

and

char * bar( char * s ) {
  s = malloc( 10 );
  return s;
}

If I now have char *a, and I say foo( a ), how is that different from
saying a = bar( a )?  I've deduced from some code that I'm writing
that I should use the second form; but why?
0
Reply Ron 11/19/2009 4:10:03 AM

On 2009-11-19, Ron Peterson (012ED25E) <peterson.ron@gmail.com> wrote:
> void foo( char *s ) {
>   s = malloc( 10 );
> }

This allocates memory, but has no other effect.

When you call a function, it is given a COPY of the arguments you pass
it.  This function modifies the local variable 's' that is its local copy
of the parameter.  It does not modify anything else.

> char * bar( char * s ) {
>   s = malloc( 10 );
>   return s;
> }

This does the same thing -- but it returns the pointer you allocated,
so you can use it later.

> If I now have char *a, and I say foo( a ), how is that different from
> saying a = bar( a )?  I've deduced from some code that I'm writing
> that I should use the second form; but why?

Imagine a function:
	void foo2(int s) {
		s = 23;
	}

Because foo(a) doesn't change a, any more than foo2(3) changes 3.

-s
-- 
Copyright 2009, all wrongs reversed.  Peter Seebach / usenet-nospam@seebs.net
http://www.seebs.net/log/ <-- lawsuits, religion, and funny pictures
http://en.wikipedia.org/wiki/Fair_Game_(Scientology) <-- get educated!
0
Reply Seebs 11/19/2009 4:17:55 AM


>void foo( char *s ) {
s here is a useless argument, since you never use its value.

>  s = malloc( 10 );
This is a memory leak.

>}
>
>and
>
>char * bar( char * s ) {
s here is a useless argument.  You never use its passed-in value.
It probably should be an automatic variable.

>  s = malloc( 10 );

C uses pass by value.  You can assign to s until you are blue in
the face, and it won't change the argument you passed in (variable
a below).

>  return s;
>}
>
>If I now have char *a, and I say foo( a ), 

Since C uses pass by value, this will not result in a changing.

>how is that different from
>saying a = bar( a )?  I've deduced from some code that I'm writing
try:    a = bar("the first argument is useless and should be removed");
>that I should use the second form; but why?

Try:

char *bar(void) {
	char	*s;
	s = malloc(10);
	return s;
}

which would be used as:

	a = bar();

0
Reply gordonb 11/19/2009 4:19:29 AM

Ron Peterson (012ED25E) wrote:
> I don't understand the difference between the following:
> 
> void foo( char *s ) {
>   s = malloc( 10 );
> }
> 
> and
> 
> char * bar( char * s ) {
>   s = malloc( 10 );
>   return s;
> }
> 
> If I now have char *a, and I say foo( a ), how is that different from
> saying a = bar( a )?  I've deduced from some code that I'm writing
> that I should use the second form; but why?

You should not use either form.
The first doesn't work and the second
makes no use of the value of the function call argument.

Both of the following are workable:

void bar( char **s )
{
     *s = malloc( 10 );
}

char *bar( void )
{
     char *s = malloc( 10 );

     return s;
}

-- 
pete
0
Reply pete 11/19/2009 4:26:09 AM

Ron Peterson (012ED25E) wrote:

> I don't understand the difference between the following:
> 
> void foo( char *s ) {
>   s = malloc( 10 );
> }

This creates a local char pointer variable named s, that is a copy of the 
pointer variable you pass to the function.

Then you allocate 10 Bytes in the free store if the malloc() call is 
successful, which are leaked when the execution of the program reaches the 
end of the scope of function foo().

That is, the char pointer variable s is destroyed, but the allocated space 
of the 10 Bytes is not released.


The correct version for the above is:


#include <stdlib.h>


void foo( char *s ) {
  s = malloc( 10 );

  free(s);
}




> 
> and
> 
> char * bar( char * s ) {
>   s = malloc( 10 );
>   return s;
> }
> 
> If I now have char *a, and I say foo( a ), how is that different from
> saying a = bar( a )?  I've deduced from some code that I'm writing
> that I should use the second form; but why?


I do not understand the question. What you probably want to do is the style:


#include <stdlib.h>


char * bar(void) {

  char *s;

  /* ... */

  s = malloc( 10 );

  // ...
  
  return s;
}




-- 
Ioannis Vranos

C95 / C++03 Software Developer

http://www.cpp-software.net
0
Reply Ioannis 11/19/2009 4:33:04 AM

On Nov 18, 11:17=A0pm, Seebs <usenet-nos...@seebs.net> wrote:

> When you call a function, it is given a COPY of the arguments you pass
> it.

Oh duh.  I haven't done any C for so long I had a total brain freeze.
Of course.  Thanks everyone.

-Ron-
0
Reply Ron 11/19/2009 4:56:56 AM

Ron Peterson (012ED25E) <peterson.ron@gmail.com> wrote:
>char * bar( char * s ) {

The others have pointed out the errors here, but I wanted to note that
there is a common idiom in the C libs to return a copy of an
operated-upon item.  For example:

   char *strcpy(char *dest, const char *src);

which returns "dest" as opposed to returning void.

The idea is, I think, that the caller might want to use the result in
some other immediate capacity.  A contrived example:

   printf("%s\n", strcpy(foo, bar));  // prints foo

That being said, I don't think I've ever seen strcpy()'s return value
used.

-Beej

0
Reply Beej 11/19/2009 6:13:12 AM

On Wed, 18 Nov 2009 23:26:09 -0500, pete wrote:

> Ron Peterson (012ED25E) wrote:
>> I don't understand the difference between the following:
>> 
>> void foo( char *s ) {
>>   s = malloc( 10 );
>> }
>> 
>> and
>> 
>> char * bar( char * s ) {
>>   s = malloc( 10 );
>>   return s;
>> }
>> 
>> If I now have char *a, and I say foo( a ), how is that different from
>> saying a = bar( a )?  I've deduced from some code that I'm writing that
>> I should use the second form; but why?
> 
> You should not use either form.
> The first doesn't work and the second makes no use of the value of the
> function call argument.
> 
> Both of the following are workable:
> 
> void bar( char **s )
> {
>      *s = malloc( 10 );
> }
> 
> char *bar( void )
> {
>      char *s = malloc( 10 );
> 
>      return s;
> }

I tried to get the returns from malloc but hit a bump somewhere:

dan@dan-desktop:~/source$  gcc -std=c99 -Wall -Wextra  malloc1.c -o out
malloc1.c: In function ‘main’:
malloc1.c:25: warning: unused variable ‘c’
dan@dan-desktop:~/source$ ./out
Segmentation fault
dan@dan-desktop:~/source$  cat malloc1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void bar( char **s )
{
     *s = malloc( 10 );
}

char *baz( void )
{
     char *s = malloc( 10 );

     return s;
}


int 
main(void)
{
  void bar ( char ** );
  char * baz ( void );
  char ** a;
  char * b;
  int c;

  bar ( a );
  b = baz( );
  #if 0
  c = * b;
  strcpy(b, "qwerty");
  printf ("%s\n", b); 
  #endif


  return 0;
}
//   gcc -std=c99 -Wall -Wextra  malloc1.c -o out
dan@dan-desktop:~/source$ 

One other thing.  I just tried to man indent to find the usage for 
setting the tablength at 4, as pete had it for his code.  How do you do 
that?
-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/19/2009 11:53:02 PM

On November 19, 2009 18:53, in comp.lang.c, frank (frank@example.invali=
d)
wrote:
[snip]
> I tried to get the returns from malloc but hit a bump somewhere:
>=20
> dan@dan-desktop:~/source$  gcc -std=3Dc99 -Wall -Wextra  malloc1.c -o=
 out
> malloc1.c: In function =E2=80=98main=E2=80=99:
> malloc1.c:25: warning: unused variable =E2=80=98c=E2=80=99
> dan@dan-desktop:~/source$ ./out
> Segmentation fault
> dan@dan-desktop:~/source$  cat malloc1.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>=20
> void bar( char **s )

Function bar accepts a pointer to a pointer-to-char, right?

> {
>      *s =3D malloc( 10 );

Here, you take that pointer to a pointer-to char, find what it points t=
o,
and change that value so that it now points to the data area you have
malloc()ed.

In other words,=20
Before the line,
  s pointed to a pointer, and that pointer pointed somewher
After the line,
  s still pointed to the same place, but the contents of that place hav=
e
  been changed to now contain the value returned by malloc()

With me so far?

> }
>=20
> char *baz( void )
> {
>      char *s =3D malloc( 10 );
>=20
>      return s;
> }
>=20
>=20
> int
> main(void)
> {
>   void bar ( char ** );
>   char * baz ( void );
>   char ** a;

Here, you allocate a as a pointer to pointer-to-char. But, you leave it=

uninitialized; a doesn't point at anything in particular (it's value is=

indeterminate).


>   char * b;
>   int c;
>=20
>   bar ( a );

Now, you pass a, an unitialized pointer to bar(). Remember what bar() w=
ill
do; it will try to modify the area that this pointer points to.

But, this pointer has an indeterminate value; it /could/ point anywhere=
,
including outside of the space in which your program and it's data resi=
de.

<off_topic>
Now, when a Unix process (that being the platform you are apparently
compiling and running on) tries to access memory outside of the bounds =
of
the process's memory map, Unix protects that memory, and sends a SIGSEG=
V
signal to the process. Uncaught, this SIGSEGV will cause the process to=

abort, with a "Segmentation Violation" error message. That's what you g=
ot.
</off_topic>

The cure for your problem is to, prior to invoking function bar(),
*initialize* the pointer so that it points at a pointer-to-char.

Given your existing code, what you really wanted to do was...

  a =3D &b;
  bar ( a );

or, in shorter form

  bar (&b);


>   b =3D baz( );
>   #if 0
>   c =3D * b;
>   strcpy(b, "qwerty");
>   printf ("%s\n", b);
>   #endif
>=20
>=20
>   return 0;
> }
> //   gcc -std=3Dc99 -Wall -Wextra  malloc1.c -o out
> dan@dan-desktop:~/source$
>=20
> One other thing.  I just tried to man indent to find the usage for
> setting the tablength at 4, as pete had it for his code.  How do you =
do
> that?

--=20
Lew Pitcher
Master Codewright & JOAT-in-training   | Registered Linux User #112576
Me: http://pitcher.digitalfreehold.ca/ | Just Linux: http://justlinux.c=
a/
----------      Slackware - Because I know what I'm doing.         ----=
--


0
Reply Lew 11/20/2009 12:04:56 AM

frank <frank@example.invalid> writes:
[...]
> I tried to get the returns from malloc but hit a bump somewhere:
[...]
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
>
> void bar( char **s )
> {
>      *s = malloc( 10 );
> }
>
> char *baz( void )
> {
>      char *s = malloc( 10 );
>
>      return s;
> }
>
>
> int 
> main(void)
> {
>   void bar ( char ** );
>   char * baz ( void );
>   char ** a;
>   char * b;
>   int c;
>
>   bar ( a );
>   b = baz( );
>   #if 0
>   c = * b;
>   strcpy(b, "qwerty");
>   printf ("%s\n", b); 
>   #endif
>
>
>   return 0;
> }
[...]

As Lew Pitcher already mentioned, the problem is that ``a'' is
uninitialized when you pass it to bar.

Since function arguments are passed by value, passing (the value of)
an uninitialized object to any function is bad news.  In your main
function above, you declare ``a'', but you don't initialize it or
assign a value to it; you then pass it as an argument in ``bar(a)''.

This is equally bad regardless of whether ``a'' is a char, a pointer,
a pointer to a pointer, or any other type of object.  The type of the
object is immaterial; referring to the value of an uninitialized
object is bad.  (The word "bad" is admittedly vague.  In this case,
it's undefined behavior; in some cases it might not be.  But it's
almost certainly not what you want to do, unless examining garbage in
memory is your idea of a good time).

> One other thing.  I just tried to man indent to find the usage for
> setting the tablength at 4, as pete had it for his code.  How do you do
> that?

Search for the word "indentation" in the man page.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply Keith 11/20/2009 12:56:46 AM

frank wrote:
> On Wed, 18 Nov 2009 23:26:09 -0500, pete wrote:
> 
> 
>>Ron Peterson (012ED25E) wrote:
>>
>>>I don't understand the difference between the following:
>>>
>>>void foo( char *s ) {
>>>  s = malloc( 10 );
>>>}
>>>
>>>and
>>>
>>>char * bar( char * s ) {
>>>  s = malloc( 10 );
>>>  return s;
>>>}
>>>
>>>If I now have char *a, and I say foo( a ), how is that different from
>>>saying a = bar( a )?  I've deduced from some code that I'm writing that
>>>I should use the second form; but why?
>>
>>You should not use either form.
>>The first doesn't work and the second makes no use of the value of the
>>function call argument.
>>
>>Both of the following are workable:
>>
>>void bar( char **s )
>>{
>>     *s = malloc( 10 );
>>}
>>
>>char *bar( void )
>>{
>>     char *s = malloc( 10 );
>>
>>     return s;
>>}
> 
> 
> I tried to get the returns from malloc but hit a bump somewhere:
> 
> dan@dan-desktop:~/source$  gcc -std=c99 -Wall -Wextra  malloc1.c -o out
> malloc1.c: In function ‘main’:
> malloc1.c:25: warning: unused variable ‘c’
> dan@dan-desktop:~/source$ ./out
> Segmentation fault
> dan@dan-desktop:~/source$  cat malloc1.c
> #include <stdio.h>
> #include <stdlib.h>
> #include <string.h>
> 
> void bar( char **s )
> {
>      *s = malloc( 10 );
> }
> 
> char *baz( void )
> {
>      char *s = malloc( 10 );
> 
>      return s;
> }
> 
> 
> int 
> main(void)
> {
>   void bar ( char ** );
>   char * baz ( void );
>   char ** a;
>   char * b;
>   int c;
> 
>   bar ( a );
>   b = baz( );
>   #if 0
>   c = * b;
>   strcpy(b, "qwerty");
>   printf ("%s\n", b); 
>   #endif
> 
> 
>   return 0;
> }

int
main(void)
{
     char *b;

     bar(&b);
     if (b != NULL) {
         strcpy(b, "qwerty");
         puts(b);
         free(b);
     }

     b = baz();
     if (b != NULL) {
         strcpy(b, "qwerty");
         puts(b);
         free(b);
     }

     return 0;
}

-- 
pete
0
Reply pete 11/20/2009 5:51:01 AM

On Thu, 19 Nov 2009 19:04:56 -0500, Lew Pitcher wrote:

> On November 19, 2009 18:53, in comp.lang.c, frank
 
> Function bar accepts a pointer to a pointer-to-char, right?
> 
>> {
>>      *s = malloc( 10 );
> 
> Here, you take that pointer to a pointer-to char, find what it points
> to, and change that value so that it now points to the data area you
> have malloc()ed.
> 
> In other words,
> Before the line,
>   s pointed to a pointer, and that pointer pointed somewher
> After the line,
>   s still pointed to the same place, but the contents of that place have
>   been changed to now contain the value returned by malloc()
> 
> With me so far?

yup.
>> int
>> main(void)
>> {
>>   void bar ( char ** );
>>   char * baz ( void );
>>   char ** a;
> 
> Here, you allocate a as a pointer to pointer-to-char. But, you leave it
> uninitialized; a doesn't point at anything in particular (it's value is
> indeterminate).
> 
> 
>>   char * b;
>>   int c;
>> 
>>   bar ( a );
> 
> Now, you pass a, an unitialized pointer to bar(). Remember what bar()
> will do; it will try to modify the area that this pointer points to.
> 
> But, this pointer has an indeterminate value; it /could/ point anywhere,
> including outside of the space in which your program and it's data
> reside.
> 
> <off_topic>
> Now, when a Unix process (that being the platform you are apparently
> compiling and running on) tries to access memory outside of the bounds
> of the process's memory map, Unix protects that memory, and sends a
> SIGSEGV signal to the process. Uncaught, this SIGSEGV will cause the
> process to abort, with a "Segmentation Violation" error message. That's
> what you got. </off_topic>
> 
> The cure for your problem is to, prior to invoking function bar(),
> *initialize* the pointer so that it points at a pointer-to-char.
> 
> Given your existing code, what you really wanted to do was...
> 
>   a = &b;
>   bar ( a );
> 
> or, in shorter form
> 
>   bar (&b);

Alright, thx Lew.  When I try to work with indirection and do it from 
scratch, I think I might resemble a beautiful animal like a caribou: 15 
minutes after it's born, covered with afterbirth, wobbly on it's too-long 
limbs.

So when you have a constructor that uses char **, what you want to do is 
declare a pointer to char and then pass it preceded by the reference 
operator, & .

I figured I would have this correct if I could print out the vlaues that 
malloc returned.  Indeed, it's plum necessary for robust code to at least 
check for a positive value.

I've got the parts here, dan@dan-desktop:~/source$ gcc -std=c99 -Wall -
Wextra  malloc1.c -o out
malloc1.c: In function ‘bar’:
malloc1.c:8: warning: initialization makes integer from pointer without a 
castdan@dan-desktop:~/source$ gcc -std=c99 -Wall -Wextra  malloc1.c -o out
malloc1.c: In function ‘bar’:
malloc1.c:8: warning: initialization makes integer from pointer without a 
cast
malloc1.c:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has 
type ‘char **’
malloc1.c:8: warning: unused variable ‘r’
malloc1.c: In function ‘main’:
malloc1.c:26: warning: unused variable ‘r’
dan@dan-desktop:~/source$ ./out
-1081554784
qwerty
0
dan@dan-desktop:~/source$ cat malloc1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void bar( char **s )
{
     *s = malloc( 10 );
     int r = &s;
     printf("%d\n", s);
}

char *baz( void )
{
     char *s = malloc( 10 );

     return s;
}


int 
main(void)
{
  void bar ( char ** );
  char * baz ( void );
  char * b;
  int c, r;

  bar ( &b );
  b = baz( );
  #if 1
  c = * b;
  strcpy(b, "qwerty");
  printf ("%s\n", b);
  printf ("%d\n", c); 
  #endif


  return 0;
}
//   gcc -std=c99 -Wall -Wextra  malloc1.c -o out
dan@dan-desktop:~/source$ 

malloc1.c:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has 
type ‘char **’
malloc1.c:8: warning: unused variable ‘r’
malloc1.c: In function ‘main’:
malloc1.c:26: warning: unused variable ‘r’
dan@dan-desktop:~/source$ ./out
-1081554784
qwerty
0
dan@dan-desktop:~/source$ cat malloc1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void bar( char **s )
{
     *s = malloc( 10 );
     int r = &s;
     printf("%d\n", s);
}

char *baz( void )
{
     char *s = malloc( 10 );

     return s;
}


int 
main(void)
{
  void bar ( char ** );
  char * baz ( void );
  char * b;
  int c, r;

  bar ( &b );
  b = baz( );
  #if 1
  c = * b;
  strcpy(b, "qwerty");
  printf ("%s\n", b);
  printf ("%d\n", c); 
  #endif


  return 0;
}
//   gcc -std=c99 -Wall -Wextra  malloc1.c -o out
dan@dan-desktop:~/source$ 
but I seem to be unable to dereference:

dan@dan-desktop:~/source$ gcc -std=c99 -Wall -Wextra  malloc1.c -o out
malloc1.c: In function ‘bar’:
malloc1.c:8: warning: initialization makes integer from pointer without a 
cast
malloc1.c:9: warning: format ‘%d’ expects type ‘int’, but argument 2 has 
type ‘char **’
malloc1.c:8: warning: unused variable ‘r’
malloc1.c: In function ‘main’:
malloc1.c:26: warning: unused variable ‘r’
dan@dan-desktop:~/source$ ./out
-1081554784
qwerty
0
dan@dan-desktop:~/source$ cat malloc1.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>

void bar( char **s )
{
     *s = malloc( 10 );
     int r = &s;
     printf("%d\n", s);
}

char *baz( void )
{
     char *s = malloc( 10 );

     return s;
}


int 
main(void)
{
  void bar ( char ** );
  char * baz ( void );
  char * b;
  int c, r;

  bar ( &b );
  b = baz( );
  #if 1
  c = * b;
  strcpy(b, "qwerty");
  printf ("%s\n", b);
  printf ("%d\n", c); 
  #endif


  return 0;
}
//   gcc -std=c99 -Wall -Wextra  malloc1.c -o out
dan@dan-desktop:~/source$ 

>> One other thing.  I just tried to man indent to find the usage for
>> setting the tablength at 4, as pete had it for his code.  How do you do
>> that?

Any takers on this one?  One problem with programs that have over fifty 
options is that you can't find the one option that any indent program 
really needs, i.e., the tab length.

-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/21/2009 6:54:53 PM

frank <frank@example.invalid> writes:
[...]
>> On November 19, 2009 18:53, in comp.lang.c, frank
[...]
>>> One other thing.  I just tried to man indent to find the usage for
>>> setting the tablength at 4, as pete had it for his code.  How do you do
>>> that?
>
> Any takers on this one?  One problem with programs that have over fifty 
> options is that you can't find the one option that any indent program 
> really needs, i.e., the tab length.

I already gave you a strong hint: "man indent" and search for the
word "indentation".  The indent program has a number of options
to control indentation for specific constructs, and one to control
overall indentation.  The man page explains it better than I could
(and, unlike anything I could tell you, is probably specific to
the version you're using).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply Keith 11/21/2009 7:04:17 PM

frank <frank@example.invalid> writes:

> On Thu, 19 Nov 2009 19:04:56 -0500, Lew Pitcher wrote:
>
>>> One other thing.  I just tried to man indent to find the usage for
>>> setting the tablength at 4, as pete had it for his code.  How do you do
>>> that?
>
> Any takers on this one?  One problem with programs that have over fifty 
> options is that you can't find the one option that any indent program 
> really needs, i.e., the tab length.

It's good manners to snip a long post like that.

On my machine "info indent", open options summary and search for
tab. 

,----
| `-tsN'
| `--tab-sizeN'
|      Set tab size to N spaces.
|      *Note Indentation::.
`----

I guess you could have guessed "length" "size" or "tab" were pertinent
search criteria :-;

-- 
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
0
Reply Richard 11/21/2009 7:29:14 PM

On Sat, 21 Nov 2009 20:29:14 +0100, Richard wrote:

> frank <frank@example.invalid> writes:
> 
>> On Thu, 19 Nov 2009 19:04:56 -0500, Lew Pitcher wrote:
>>
>>>> One other thing.  I just tried to man indent to find the usage for
>>>> setting the tablength at 4, as pete had it for his code.  How do you
>>>> do that?
>>
>> Any takers on this one?  One problem with programs that have over fifty
>> options is that you can't find the one option that any indent program
>> really needs, i.e., the tab length.
> 
> It's good manners to snip a long post like that.

Oops, sorry.  I didn't want to snip too much of Lew's comments, because 
I'm not quite straightened out on this yet.  I over-selected out of 
terminal to get way too much of it.  :(
> 
> On my machine "info indent", open options summary and search for tab.
> 
> ,----
> | `-tsN'
> | `--tab-sizeN'
> |      Set tab size to N spaces.
> |      *Note Indentation::.
> `----
> 
> I guess you could have guessed "length" "size" or "tab" were pertinent
> search criteria :-;

dan@dan-desktop:~/source$ indent -i4 malloc1.c

This works.
-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/21/2009 10:44:42 PM

On Sat, 21 Nov 2009 11:04:17 -0800, Keith Thompson wrote:

> frank <frank@example.invalid> writes: [...]
>>> On November 19, 2009 18:53, in comp.lang.c, frank
> [...]
>>>> One other thing.  I just tried to man indent to find the usage for
>>>> setting the tablength at 4, as pete had it for his code.  How do you
>>>> do that?
>>
>> Any takers on this one?  One problem with programs that have over fifty
>> options is that you can't find the one option that any indent program
>> really needs, i.e., the tab length.
> 
> I already gave you a strong hint: "man indent" and search for the word
> "indentation".  The indent program has a number of options to control
> indentation for specific constructs, and one to control overall
> indentation.  The man page explains it better than I could (and, unlike
> anything I could tell you, is probably specific to the version you're
> using).

Sorry, Keith, I didn't see a response before.  Am I the only person whose 
newsreader doesn't see the original post in these threads?

I must have looked right past it a couple times.  I really struggle to 
get useful things out of the man pages.  Besides all of the learning 
curve of dealing with a new paradigm for an OS, it doesn't really want to 
respond to my keyboard or mouse.  It takes over a terminal and steps on 
everything I'm doing.  Maybe I will come to like this spartan reference.  
Maybe linux users might raise their standards for help materials.
-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/21/2009 10:54:35 PM

On Thu, 19 Nov 2009 06:33:04 +0200, Ioannis Vranos wrote:

>> I don't understand the difference between the following:
>> 
>> void foo( char *s ) {
>>   s = malloc( 10 );
>> }
> 
> This creates a local char pointer variable named s, that is a copy of
> the pointer variable you pass to the function.
> 
> Then you allocate 10 Bytes in the free store if the malloc() call is
> successful, which are leaked when the execution of the program reaches
> the end of the scope of function foo().
> 
> That is, the char pointer variable s is destroyed, but the allocated
> space of the 10 Bytes is not released.
> 
> 
> The correct version for the above is:
> 
> 
> #include <stdlib.h>
> 
> 
> void foo( char *s ) {
>   s = malloc( 10 );
> 
>   free(s);
> }
> 
>

I think "correctness" is a function of what you want to have happen.  If 
foo is to be a constructor, then the responsibility to free s goes to the 
caller.
-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/21/2009 11:48:43 PM

frank <frank@example.invalid> writes:

> On Thu, 19 Nov 2009 06:33:04 +0200, Ioannis Vranos wrote:
>
>>> I don't understand the difference between the following:
>>> 
>>> void foo( char *s ) {
>>>   s = malloc( 10 );
>>> }
>> 
>> This creates a local char pointer variable named s, that is a copy of
>> the pointer variable you pass to the function.
>> 
>> Then you allocate 10 Bytes in the free store if the malloc() call is
>> successful, which are leaked when the execution of the program reaches
>> the end of the scope of function foo().
>> 
>> That is, the char pointer variable s is destroyed, but the allocated
>> space of the 10 Bytes is not released.
>> 
>> 
>> The correct version for the above is:
>> 
>> 
>> #include <stdlib.h>
>> 
>> 
>> void foo( char *s ) {
>>   s = malloc( 10 );
>> 
>>   free(s);
>> }
>> 
>>
>
> I think "correctness" is a function of what you want to have happen.  If 
> foo is to be a constructor, then the responsibility to free s goes to the 
> caller.

You don't pass the results of the malloc back to the caller so how do
you expect to free it?

-- 
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
0
Reply Richard 11/21/2009 11:55:10 PM

frank <frank@example.invalid> writes:
> On Sat, 21 Nov 2009 20:29:14 +0100, Richard wrote:
[...]
>> On my machine "info indent", open options summary and search for tab.
>> 
>> ,----
>> | `-tsN'
>> | `--tab-sizeN'
>> |      Set tab size to N spaces.
>> |      *Note Indentation::.
>> `----
>> 
>> I guess you could have guessed "length" "size" or "tab" were pertinent
>> search criteria :-;
>
> dan@dan-desktop:~/source$ indent -i4 malloc1.c
>
> This works.

And that's my preference as well.  The "-ts" or "--tab-size"
option is useful only if you want to use tabs for indentation.
Opinions on this vary widely, but personally I strongly prefer to
use only spaces for indentation.

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Nokia
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"
0
Reply Keith 11/22/2009 1:20:53 AM

On Sat, 21 Nov 2009 17:20:53 -0800, Keith Thompson wrote:

> frank <frank@example.invalid> writes:
>> On Sat, 21 Nov 2009 20:29:14 +0100, Richard wrote:
> [...]
>>> On my machine "info indent", open options summary and search for tab.
>>> 
>>> ,----
>>> | `-tsN'
>>> | `--tab-sizeN'
>>> |      Set tab size to N spaces.
>>> |      *Note Indentation::.
>>> `----
>>> 
>>> I guess you could have guessed "length" "size" or "tab" were pertinent
>>> search criteria :-;
>>
>> dan@dan-desktop:~/source$ indent -i4 malloc1.c
>>
>> This works.
> 
> And that's my preference as well.  The "-ts" or "--tab-size" option is
> useful only if you want to use tabs for indentation. Opinions on this
> vary widely, but personally I strongly prefer to use only spaces for
> indentation.

People who would rather have tabs than the equivalent whitespace must 
have less frustration with them than I do.
-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/22/2009 1:35:00 AM

On Sun, 22 Nov 2009 00:55:10 +0100, Richard wrote:

>> I think "correctness" is a function of what you want to have happen. 
>> If foo is to be a constructor, then the responsibility to free s goes
>> to the caller.
> 
> You don't pass the results of the malloc back to the caller so how do
> you expect to free it?

Elsesubthread, I have not *yet* gotten a constructor to interact with a 
caller so as to create memory and pass back the means to do something 
with it.  Don't bet against me for too long.
-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/22/2009 2:07:32 AM

frank <frank@example.invalid> writes:

> On Sun, 22 Nov 2009 00:55:10 +0100, Richard wrote:
>
>>> I think "correctness" is a function of what you want to have happen. 
>>> If foo is to be a constructor, then the responsibility to free s goes
>>> to the caller.
>> 
>> You don't pass the results of the malloc back to the caller so how do
>> you expect to free it?
>
> Elsesubthread, I have not *yet* gotten a constructor to interact with a 
> caller so as to create memory and pass back the means to do something 
> with it.  Don't bet against me for too long.

It's nothing clever.

>>> void foo( char *s ) {
>>>   s = malloc( 10 );
>>> }

Above you are not using your s that you pass in.

Keeping it simple

char * foo()
{
return malloc(10);
}

or maybe your pass in a ppointer to the location where you want to store
the pointer to the new memory?

char * newPointer(char **p)
{
   return *p = malloc(10);
}

etc etc etc

A lot of people would have you checking your pointers for null condition
time and time again. I would advise against that since in many calls you
know the pointer can not be NULL and rechecking would be wasteful. Only
you and the code framework you build can decide that however. Depends on
the flow of the application.



-- 
"Avoid hyperbole at all costs, its the most destructive argument on
the planet" - Mark McIntyre in comp.lang.c
0
Reply Richard 11/22/2009 2:27:21 AM

frank <frank@example.invalid> writes:
> On Sat, 21 Nov 2009 17:20:53 -0800, Keith Thompson wrote:
>> frank <frank@example.invalid> writes:
>>> On Sat, 21 Nov 2009 20:29:14 +0100, Richard wrote:
>> [...]
>>>> On my machine "info indent", open options summary and search for tab.
>>>> 
>>>> ,----
>>>> | `-tsN'
>>>> | `--tab-sizeN'
>>>> |      Set tab size to N spaces.
>>>> |      *Note Indentation::.
>>>> `----
>>>> 
>>>> I guess you could have guessed "length" "size" or "tab" were pertinent
>>>> search criteria :-;
>>>
>>> dan@dan-desktop:~/source$ indent -i4 malloc1.c
>>>
>>> This works.
>> 
>> And that's my preference as well.  The "-ts" or "--tab-size" option is
>> useful only if you want to use tabs for indentation. Opinions on this
>> vary widely, but personally I strongly prefer to use only spaces for
>> indentation.
>
> People who would rather have tabs than the equivalent whitespace must 
> have less frustration with them than I do.

The entire linux development community seems to cope. I thought I'd hate
it at first, but putting all responsibility for indenting on my editor
makes it a no-brainer. Keeping lines less than 80 characters in width
is the only hard part. (This massive indentation of course is probably
one of the reasons that echelons of ifs are rendered instead as a flat
sequence of gotos, which many view as a step backwards.)

Phil
-- 
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
0
Reply Phil 11/22/2009 12:06:53 PM

On Sun, 22 Nov 2009 14:06:53 +0200, Phil Carmody wrote:

> frank <frank@example.invalid> writes:
>> On Sat, 21 Nov 2009 17:20:53 -0800, Keith Thompson wrote:

>>> And that's my preference as well.  The "-ts" or "--tab-size" option is
>>> useful only if you want to use tabs for indentation. Opinions on this
>>> vary widely, but personally I strongly prefer to use only spaces for
>>> indentation.
>>
>> People who would rather have tabs than the equivalent whitespace must
>> have less frustration with them than I do.
> 
> The entire linux development community seems to cope. I thought I'd hate
> it at first, but putting all responsibility for indenting on my editor
> makes it a no-brainer. Keeping lines less than 80 characters in width is
> the only hard part. (This massive indentation of course is probably one
> of the reasons that echelons of ifs are rendered instead as a flat
> sequence of gotos, which many view as a step backwards.)
> 
> Phil

This might shock you, but Jacob's lcc is one of the better windows tools 
for C.  You really can't pull the whole thing off on a command line like 
you can on a terminal with linux.  So windows-users need an IDE, and tabs 
confuse the heck out of them, in particular when you're adding keystrokes 
here and pasting in a subroutine there.

The obvious remedy is "switch to linux," but I was only able to pull it 
off because my good friend here in the Duke City is a sysadmin and able 
to straighten me out on this stuff.
-- 
frank

"Guns: yes, they are harmful."
0
Reply frank 11/23/2009 1:36:03 AM

frank <frank@example.invalid> writes:
> On Sun, 22 Nov 2009 14:06:53 +0200, Phil Carmody wrote:
>> frank <frank@example.invalid> writes:
>>> On Sat, 21 Nov 2009 17:20:53 -0800, Keith Thompson wrote:
>
>>>> And that's my preference as well.  The "-ts" or "--tab-size" option is
>>>> useful only if you want to use tabs for indentation. Opinions on this
>>>> vary widely, but personally I strongly prefer to use only spaces for
>>>> indentation.
>>>
>>> People who would rather have tabs than the equivalent whitespace must
>>> have less frustration with them than I do.
>> 
>> The entire linux development community seems to cope. I thought I'd hate
>> it at first, but putting all responsibility for indenting on my editor
>> makes it a no-brainer. Keeping lines less than 80 characters in width is
>> the only hard part. (This massive indentation of course is probably one
>> of the reasons that echelons of ifs are rendered instead as a flat
>> sequence of gotos, which many view as a step backwards.)
>> 
>> Phil
>
> This might shock you, but Jacob's lcc is one of the better windows tools 
> for C.  You really can't pull the whole thing off on a command line like 
> you can on a terminal with linux.  So windows-users need an IDE, and tabs 
> confuse the heck out of them, in particular when you're adding keystrokes 
> here and pasting in a subroutine there.

You're confusing 'shock' for 'complete disinterest'.

'One of the better windows tools' is a phrase as meaningful to me
as 'one of the nicer smelling farts'.

> The obvious remedy is "switch to linux," but I was only able to pull it 
> off because my good friend here in the Duke City is a sysadmin and able 
> to straighten me out on this stuff.

There's also an internet out there, bellieve it or not; the IRC channels 
are great for assistance in the debian-based arena (so ubuntu too).

Phil
-- 
Any true emperor never needs to wear clothes. -- Devany on r.a.s.f1
0
Reply Phil 11/26/2009 12:04:38 AM

On 26 Nov, 00:04, Phil Carmody <thefatphil_demun...@yahoo.co.uk>
wrote:
> frank <fr...@example.invalid> writes:
> > On Sun, 22 Nov 2009 14:06:53 +0200, Phil Carmody wrote:
> >> frank <fr...@example.invalid> writes:
> >>> On Sat, 21 Nov 2009 17:20:53 -0800, Keith Thompson wrote:

> >>>> And that's my preference as well. =A0The "-ts" or "--tab-size" optio=
n is
> >>>> useful only if you want to use tabs for indentation. Opinions on thi=
s
> >>>> vary widely, but personally I strongly prefer to use only spaces for
> >>>> indentation.

me too. I loathe tabs.

> >>> People who would rather have tabs than the equivalent whitespace must
> >>> have less frustration with them than I do.
>
> >> The entire linux development community seems to cope. I thought I'd ha=
te
> >> it at first, but putting all responsibility for indenting on my editor
> >> makes it a no-brainer. Keeping lines less than 80 characters in width =
is
> >> the only hard part. (This massive indentation of course is probably on=
e
> >> of the reasons that echelons of ifs are rendered instead as a flat
> >> sequence of gotos, which many view as a step backwards.)

if your layout standard pushes you towards gots then your layout
standard needs re-thinking. But I don't find sticking to 80 colums
particularly difficult and I *never* use goto (the last time I did an
Italian collegue decribed me as a "software beast"- a title carry with
pride).

> > This might shock you, but Jacob's lcc is one of the better windows tool=
s
> > for C. =A0You really can't pull the whole thing off on a command line l=
ike
> > you can on a terminal with linux.

why not? I mean I like IDEs but I don't see why lcc couldn't run as
command line tool. gcc does and gcc runs on windows. I'm pretty sure
you could run Microsoft's compiler from a command line. gcc has
zillions of command line options but no one claims it can't be run
from a command line.

> >=A0So windows-users need an IDE,

I don't accept this

> > and tabs confuse the heck out of them,

no they don't. I've maintained tabbed code on Visual Studio and VC
does not get confused. If you editor is set up to match the tab
spacing used by the code there is no problem. I personnally don't like
tabs and I do like IDEs but you shouldn't use arguments that don't
seem to be true.

> > in particular when you're adding keystrokes
> > here and pasting in a subroutine there.

I have never had a problem and I don't see why an IDE would make a
difference. But then I use a windows (in this case I don't necessarily
mean MS Windows) based editor for Unix code as well. What is so
special about unix editors that you claim they handle tabs better than
MS Windows editors can?

<snip>


--
    During the day as you start up many applications the computer
Random
    Access Memory is used to support these applications. Eventually
the
    computer will start to slow down as more memory is put into use.
    Shutting applications down quite often does not release all the
    memory back into use. Restarting the computer each day will start
the
    day with a clear memory - enabling the computer to go faster.
            (advice from IT)
0
Reply Nick 11/26/2009 9:13:34 AM

25 Replies
57 Views

(page loaded in 0.472 seconds)

Similiar Articles:


















7/29/2012 4:21:48 AM


Reply: