Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > comp.lang.c > #105980 > unrolled thread

Two C code questions

Started byMehdiAmini <atorrses@gmail.com>
First post2017-03-14 07:15 +0330
Last post2017-03-14 14:14 -0700
Articles 13 — 7 participants

Back to article view | Back to comp.lang.c


Contents

  Two C code questions MehdiAmini <atorrses@gmail.com> - 2017-03-14 07:15 +0330
    Re: Two C code questions Joe Pfeiffer <pfeiffer@cs.nmsu.edu> - 2017-03-13 22:13 -0600
    Re: Two C code questions Ian Collins <ian-news@hotmail.com> - 2017-03-14 17:16 +1300
    Re: Two C code questions Ike Naar <ike@iceland.freeshell.org> - 2017-03-14 07:20 +0000
      Re: Two C code questions MehdiAmini <atorrses@gmail.com> - 2017-03-14 12:01 +0330
        Re: Two C code questions Ike Naar <ike@iceland.freeshell.org> - 2017-03-14 19:23 +0000
          Re: Two C code questions Keith Thompson <kst-u@mib.org> - 2017-03-14 12:40 -0700
    Re: Two C code questions scott@slp53.sl.home (Scott Lurndal) - 2017-03-14 12:44 +0000
    Re: Two C code questions Keith Thompson <kst-u@mib.org> - 2017-03-14 08:53 -0700
      Re: Two C code questions MehdiAmini <atorrses@gmail.com> - 2017-03-15 14:05 +0330
    Re: Two C code questions John Bode <jfbode1029@gmail.com> - 2017-03-14 10:38 -0700
      Re: Two C code questions Keith Thompson <kst-u@mib.org> - 2017-03-14 11:49 -0700
        Re: Two C code questions John Bode <jfbode1029@gmail.com> - 2017-03-14 14:14 -0700

#105980 — Two C code questions

FromMehdiAmini <atorrses@gmail.com>
Date2017-03-14 07:15 +0330
SubjectTwo C code questions
Message-ID<oa7oru$rkf$1@dont-email.me>
// Clang version 3.8.0

// Question 1:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

void my_alloc( void *, size_t );

int main(void)
{
     unsigned *u_ptr = NULL;
     //unsigned *u_ptr; // Why using this instead of above line causes 
core dump?

     my_alloc(u_ptr,sizeof(*u_ptr));

     free(u_ptr);
     return EXIT_SUCCESS;
}

void my_alloc( void *v_ptr, size_t size )
{
     v_ptr = malloc(size);
     if( v_ptr == NULL )
     {
         fprintf(stderr,"Memory allocation failed.\n");
         exit(EXIT_FAILURE);
     }

     return ;
}

// Question 2:
#include <stdio.h>
#include <stdlib.h>
#include <inttypes.h>

#define N 6
//static const long N = 6; // Why using this instead of above line 
causes error?

int main(void)
{
     uint64_t ui[N] = {0};

     return EXIT_SUCCESS;
}

-- 
Farewell.

[toc] | [next] | [standalone]


#105981

FromJoe Pfeiffer <pfeiffer@cs.nmsu.edu>
Date2017-03-13 22:13 -0600
Message-ID<1b7f3sfqce.fsf@pfeifferfamily.net>
In reply to#105980
MehdiAmini <atorrses@gmail.com> writes:

> // Clang version 3.8.0
>
> // Question 1:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> void my_alloc( void *, size_t );
>
> int main(void)
> {
>     unsigned *u_ptr = NULL;
>     //unsigned *u_ptr; // Why using this instead of above line causes
> core dump?

Looking at the man page:  "The  free()  function frees  the memory space
pointed to by ptr, which must have been returned by a previous call to
malloc(), calloc(), or realloc().  Otherwise, or if free(ptr) has
already been called before, undefined behavior occurs. If ptr is NULL,
no operation is performed."  You're passing it a pointer that hasn't
been allocated by one of the necessary functions, so you can expect Bad
Things to happen.

The reason (other than the man page saying Don't Do That) is the pointer
is essentially random when you don't initialize it, so it's either
pointing into a location you can't access at all or one that isn't
properly set up as part of the free space pool.

>     my_alloc(u_ptr,sizeof(*u_ptr));
>
>     free(u_ptr);
>     return EXIT_SUCCESS;
> }
>
> void my_alloc( void *v_ptr, size_t size )
> {
>     v_ptr = malloc(size);
>     if( v_ptr == NULL )
>     {
>         fprintf(stderr,"Memory allocation failed.\n");
>         exit(EXIT_FAILURE);
>     }
>
>     return ;
> }
>
> // Question 2:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> #define N 6
> //static const long N = 6; // Why using this instead of above line
> causes error?

Because you can't initialize a variable length array.  Yes, N is a const
int, but that doesn't make it a "constant" for purposes of setting the
length of the array.

> int main(void)
> {
>     uint64_t ui[N] = {0};
>
>     return EXIT_SUCCESS;
> }

[toc] | [prev] | [next] | [standalone]


#105982

FromIan Collins <ian-news@hotmail.com>
Date2017-03-14 17:16 +1300
Message-ID<eip94fFhe9iU4@mid.individual.net>
In reply to#105980
On 03/14/17 04:45 PM, MehdiAmini wrote:
> // Clang version 3.8.0
>
> // Question 1:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> void my_alloc( void *, size_t );
>
> int main(void)
> {
>       unsigned *u_ptr = NULL;
>       //unsigned *u_ptr; // Why using this instead of above line causes
> core dump?
>
>       my_alloc(u_ptr,sizeof(*u_ptr));
>
>       free(u_ptr);
>       return EXIT_SUCCESS;
> }

The answer to why it causes a crash is the value of u_ptr is garbage. 
It is safe to pass NULL to free, but not garbage..

> void my_alloc( void *v_ptr, size_t size )
> {
>       v_ptr = malloc(size);
>       if( v_ptr == NULL )
>       {
>           fprintf(stderr,"Memory allocation failed.\n");
>           exit(EXIT_FAILURE);
>       }
>
>       return ;
> }

The first parameter should b "void**", a pointer to a void pointer. 
Otherwise all you are doing is assigning to the function parameter, with 
is local to the function.

With the correct parameter type, use:

  *v_ptr = malloc(size);


> // Question 2:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> #define N 6
> //static const long N = 6; // Why using this instead of above line
> causes error?
>
> int main(void)
> {
>       uint64_t ui[N] = {0};

C doesn't have a proper const, so you will be creating a variable length 
array which cannot be initialised.

-- 
Ian

[toc] | [prev] | [next] | [standalone]


#105992

FromIke Naar <ike@iceland.freeshell.org>
Date2017-03-14 07:20 +0000
Message-ID<slrn3vfsocf6iq.9m.ike@iceland.freeshell.org>
In reply to#105980
On 2017-03-14, MehdiAmini <atorrses@gmail.com> wrote:
> // Clang version 3.8.0
>
> // Question 1:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> void my_alloc( void *, size_t );
>
> int main(void)
> {
>      unsigned *u_ptr = NULL;
>      //unsigned *u_ptr; // Why using this instead of above line causes 
> core dump?
>
>      my_alloc(u_ptr,sizeof(*u_ptr));
>
>      free(u_ptr);
>      return EXIT_SUCCESS;
> }
>
> void my_alloc( void *v_ptr, size_t size )
> {
>      v_ptr = malloc(size);
>      if( v_ptr == NULL )
>      {
>          fprintf(stderr,"Memory allocation failed.\n");
>          exit(EXIT_FAILURE);
>      }
>
>      return ;
> }
>
> // Question 2:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> #define N 6
> //static const long N = 6; // Why using this instead of above line 
> causes error?
>
> int main(void)
> {
>      uint64_t ui[N] = {0};
>
>      return EXIT_SUCCESS;
> }

Both questions are answered in the C language FAQ

  http://c-faq.com

look for questions 4.8 and 8.11 .

[toc] | [prev] | [next] | [standalone]


#105997

FromMehdiAmini <atorrses@gmail.com>
Date2017-03-14 12:01 +0330
Message-ID<oa89is$452$1@dont-email.me>
In reply to#105992
On 03/14/2017 10:50 AM, Ike Naar wrote:

[...]
>
> Both questions are answered in the C language FAQ
>
>   http://c-faq.com
>
> look for questions 4.8 and 8.11 .
>

I can not find question 8.11 .

-- 
Farewell.

[toc] | [prev] | [next] | [standalone]


#106077

FromIke Naar <ike@iceland.freeshell.org>
Date2017-03-14 19:23 +0000
Message-ID<slrn3vfsocgguv.28d.ike@iceland.freeshell.org>
In reply to#105997
On 2017-03-14, MehdiAmini <atorrses@gmail.com> wrote:
> On 03/14/2017 10:50 AM, Ike Naar wrote:
>
> [...]
>>
>> Both questions are answered in the C language FAQ
>>
>>   http://c-faq.com
>>
>> look for questions 4.8 and 8.11 .
>>
>
> I can not find question 8.11 .

Sorry, it's 11.8

[toc] | [prev] | [next] | [standalone]


#106080

FromKeith Thompson <kst-u@mib.org>
Date2017-03-14 12:40 -0700
Message-ID<lnlgs7ir3x.fsf@kst-u.example.com>
In reply to#106077
Ike Naar <ike@iceland.freeshell.org> writes:
> On 2017-03-14, MehdiAmini <atorrses@gmail.com> wrote:
>> On 03/14/2017 10:50 AM, Ike Naar wrote:
>>
>> [...]
>>>
>>> Both questions are answered in the C language FAQ
>>>
>>>   http://c-faq.com
>>>
>>> look for questions 4.8 and 8.11 .
>>>
>>
>> I can not find question 8.11 .
>
> Sorry, it's 11.8

See, endianness matters!

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#106007

Fromscott@slp53.sl.home (Scott Lurndal)
Date2017-03-14 12:44 +0000
Message-ID<QARxA.14896$zC6.13948@fx29.iad>
In reply to#105980
MehdiAmini <atorrses@gmail.com> writes:
>// Clang version 3.8.0
>
>// Question 1:
>#include <stdio.h>
>#include <stdlib.h>
>#include <inttypes.h>
>
>void my_alloc( void *, size_t );
>
>int main(void)
>{
>     unsigned *u_ptr = NULL;
>     //unsigned *u_ptr; // Why using this instead of above line causes 
>core dump?
>
>     my_alloc(u_ptr,sizeof(*u_ptr));
>
>     free(u_ptr);
>     return EXIT_SUCCESS;
>}
>
>void my_alloc( void *v_ptr, size_t size )
>{
>     v_ptr = malloc(size);

This doesn't do what you think it does.

[toc] | [prev] | [next] | [standalone]


#106041

FromKeith Thompson <kst-u@mib.org>
Date2017-03-14 08:53 -0700
Message-ID<lntw6vkg6v.fsf@kst-u.example.com>
In reply to#105980
MehdiAmini <atorrses@gmail.com> writes:
> // Clang version 3.8.0
>
> // Question 1:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> void my_alloc( void *, size_t );
>
> int main(void)
> {
>      unsigned *u_ptr = NULL;
>      //unsigned *u_ptr; // Why using this instead of above line causes 
> core dump?
>
>      my_alloc(u_ptr,sizeof(*u_ptr));
>
>      free(u_ptr);
>      return EXIT_SUCCESS;
> }

Function arguments are passed by value, always.

You are passing the *value* of u_ptr to my_alloc.  If you don't
initialize it, that value is garbage.  It turns out that probably
doesn't matter, because my_alloc never uses the value you passed in.

Since a function cannot change the value of u_ptr, you're passing a
garbage value to free().  That's what causes the core dump.

> void my_alloc( void *v_ptr, size_t size )
> {

Here v_ptr hold a copy of the (garbage) value of u_ptr.

>      v_ptr = malloc(size);

Here you overwrite that garbage value with the value returned by
malloc.

>      if( v_ptr == NULL )
>      {
>          fprintf(stderr,"Memory allocation failed.\n");
>          exit(EXIT_FAILURE);
>      }
>
>      return ;

And here that value is discarded, since v_ptr is local to your function.
(The return statement is unnecesary but harmless.)

> }
>
> // Question 2:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
>
> #define N 6
> //static const long N = 6; // Why using this instead of above line 
> causes error?

It would have been helpful if you had included the text of the error
message.  Using gcc, I get:

    error: variable-sized object may not be initialized

When you define
    static const long N = 6;
you're *not* creating a compile-time constant.  You're (at least
logically) creating an object named N, with an initial value of 6.  All
"const" does is forbid any attempt to modify it.  ("const" doesn't mean
"constant", it means "read-only").

(In C++, N would be a compile-time constant.  Even in C, most compilers
will treat it as one, but that's an optimization that doesn't affect
what you can legally do with it.)

> int main(void)
> {
>      uint64_t ui[N] = {0};

Since N is not a constant, ui is a VLA (variable length array), and the
language rules don't allow an initializer for a VLA.  (Allowing
initializers would require the compiler to generate code to figure out
*at run time* how many elements to initialize.)

>      return EXIT_SUCCESS;
> }

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#106126

FromMehdiAmini <atorrses@gmail.com>
Date2017-03-15 14:05 +0330
Message-ID<oab57m$pcv$1@dont-email.me>
In reply to#106041
On 03/14/2017 07:23 PM, Keith Thompson wrote:

[...]

> It would have been helpful if you had included the text of the error
> message.  Using gcc, I get:
>
>     error: variable-sized object may not be initialized
>

[...]

// Clang version 3.8.0

clang   -pedantic -Weverything -Wall -std=c99 -m64

warning: variable length array used [-Wvla]
     uint64_t ui[N] = {0};
                ^

error: variable-sized object may not be initialized
     uint64_t ui[N] = {0};
                 ^
1 warning and 1 error generated.

-- 
Farewell.

[toc] | [prev] | [next] | [standalone]


#106064

FromJohn Bode <jfbode1029@gmail.com>
Date2017-03-14 10:38 -0700
Message-ID<468c93a0-7b2d-4eab-8266-39737867b9ac@googlegroups.com>
In reply to#105980
On Monday, March 13, 2017 at 10:45:53 PM UTC-5, Mehdi Amini Valashani son of Bahram wrote:
> // Clang version 3.8.0
> 
> // Question 1:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
> 
> void my_alloc( void *, size_t );
> 
> int main(void)
> {
>      unsigned *u_ptr = NULL;
>      //unsigned *u_ptr; // Why using this instead of above line causes 
> core dump?
> 

Because the following function call doesn't actually modify the value of
u_ptr - if it was an invalid, non-NULL value before the call to my_alloc,
it's *still* an invalid, non-NULL value after the call.  

>      my_alloc(u_ptr,sizeof(*u_ptr));
> 

Remember that if you want a function to write a new value to a parameter, 
then you must pass a *pointer to that parameter*.  You'd need to change 
the call to 

    my_alloc( &u_ptr, sizeof( *u_ptr ) );

and change the function definition to

    void m_alloc( void **v_ptr, size_t size )
    {
      *v_ptr = malloc( size );
      if ( *v_ptr == NULL )
      {
        // bail out
      }
    }

> 
> // Question 2:
> #include <stdio.h>
> #include <stdlib.h>
> #include <inttypes.h>
> 
> #define N 6
> //static const long N = 6; // Why using this instead of above line 
> causes error?
> 

It would help if you told us what the actual error is.

> int main(void)
> {
>      uint64_t ui[N] = {0};
> 

For C89 and earlier, array dimensions must be *constant expressions*; i.e.,
something that can be evaluated at compile time (integer literals, sizeof
expressions, macros that expand to either literals or sizeof expressions,
arithmetic expressions that involve any of the previous, etc.).  

A variable declared as "static const" is *not* a constant expression - its
value is not evaluated at compile time.  

C99 introduced variable-length arrays, whose size doesn't have to be 
established until run time; if you compiled that code under a C99 compiler,
it should work.  

[toc] | [prev] | [next] | [standalone]


#106069

FromKeith Thompson <kst-u@mib.org>
Date2017-03-14 11:49 -0700
Message-ID<lnzignitgp.fsf@kst-u.example.com>
In reply to#106064
John Bode <jfbode1029@gmail.com> writes:
> On Monday, March 13, 2017 at 10:45:53 PM UTC-5, Mehdi Amini Valashani son of Bahram wrote:
[...]
>> int main(void)
>> {
>>      uint64_t ui[N] = {0};
>> 
>
> For C89 and earlier, array dimensions must be *constant expressions*; i.e.,
> something that can be evaluated at compile time (integer literals, sizeof
> expressions, macros that expand to either literals or sizeof expressions,
> arithmetic expressions that involve any of the previous, etc.).  
>
> A variable declared as "static const" is *not* a constant expression - its
> value is not evaluated at compile time.  
>
> C99 introduced variable-length arrays, whose size doesn't have to be 
> established until run time; if you compiled that code under a C99 compiler,
> it should work.  

No, C99 doesn't allow VLAs to be initialized (nor does C11).

-- 
Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
Working, but not speaking, for JetHead Development, Inc.
"We must do something.  This is something.  Therefore, we must do this."
    -- Antony Jay and Jonathan Lynn, "Yes Minister"

[toc] | [prev] | [next] | [standalone]


#106094

FromJohn Bode <jfbode1029@gmail.com>
Date2017-03-14 14:14 -0700
Message-ID<95e48742-3943-4b03-910b-c62e5ab8caa1@googlegroups.com>
In reply to#106069
On Tuesday, March 14, 2017 at 1:50:05 PM UTC-5, Keith Thompson wrote:
> John Bode <jfbode1029@gmail.com> writes:
> > On Monday, March 13, 2017 at 10:45:53 PM UTC-5, Mehdi Amini Valashani son of Bahram wrote:
> [...]
> >> int main(void)
> >> {
> >>      uint64_t ui[N] = {0};
> >> 
> >
> > For C89 and earlier, array dimensions must be *constant expressions*; i.e.,
> > something that can be evaluated at compile time (integer literals, sizeof
> > expressions, macros that expand to either literals or sizeof expressions,
> > arithmetic expressions that involve any of the previous, etc.).  
> >
> > A variable declared as "static const" is *not* a constant expression - its
> > value is not evaluated at compile time.  
> >
> > C99 introduced variable-length arrays, whose size doesn't have to be 
> > established until run time; if you compiled that code under a C99 compiler,
> > it should work.  
> 
> No, C99 doesn't allow VLAs to be initialized (nor does C11).
> 
> -- 
> Keith Thompson (The_Other_Keith) kst-u@mib.org  <http://www.ghoti.net/~kst>
> Working, but not speaking, for JetHead Development, Inc.
> "We must do something.  This is something.  Therefore, we must do this."
>     -- Antony Jay and Jonathan Lynn, "Yes Minister"

Bah.  I knew that.

Shouldn't post when I'm working on other stuff. 

[toc] | [prev] | [standalone]


Back to top | Article view | comp.lang.c


csiph-web