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


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

Understanding the program that has pointers to two_dimensional arrays

Started byAlla _ <modelling.data@gmail.com>
First post2016-12-05 07:45 -0800
Last post2016-12-05 12:50 -0500
Articles 3 on this page of 23 — 5 participants

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


Contents

  Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 07:45 -0800
    Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-05 17:03 +0000
      Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 09:43 -0800
        Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-05 18:16 +0000
          Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 22:46 -0800
            Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 10:23 +0000
              Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 02:53 -0800
                Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 10:58 +0000
                  Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 03:42 -0800
                  Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 06:31 -0800
                    Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 14:49 +0000
                      Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 08:22 -0800
                        Re: Understanding the program that has pointers to two_dimensional arrays Richard Heathfield <rjh@cpax.org.uk> - 2016-12-06 16:48 +0000
                          Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-06 09:15 -0800
            Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-06 08:20 -0800
          Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 22:53 -0800
    Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-05 09:26 -0800
      Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 09:47 -0800
        Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-05 12:10 -0800
      Re: Understanding the program that has pointers to two_dimensional arrays Alla _ <modelling.data@gmail.com> - 2016-12-05 10:00 -0800
      Re: Understanding the program that has pointers to two_dimensional arrays Ben Bacarisse <ben.usenet@bsb.me.uk> - 2016-12-05 19:11 +0000
        Re: Understanding the program that has pointers to two_dimensional arrays Keith Thompson <kst-u@mib.org> - 2016-12-05 12:21 -0800
    Re: Understanding the program that has pointers to two_dimensional arrays "James R. Kuyper" <jameskuyper@verizon.net> - 2016-12-05 12:50 -0500

Page 2 of 2 — ← Prev page 1 [2]


#98041

FromBen Bacarisse <ben.usenet@bsb.me.uk>
Date2016-12-05 19:11 +0000
Message-ID<87zikagpiw.fsf@bsb.me.uk>
In reply to#98025
Keith Thompson <kst-u@mib.org> writes:

> Alla _ <modelling.data@gmail.com> writes:
<snip>
>>         // Print the title
>>          printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
>
> The author of this program certainly likes newlines, but omits them at
> the ends of lines.  I see this kind of thing in program written for
> Windows.  Perhaps there's some reason to print three blank lines before
> the title.  Normally every line of output should end in a newline.

I've noticed the same thing in a lot of C tutorials, though I've never
made any connection with Windows (I wasn't paying attention to the OS).
I think it may simply derive from the name of the character: "newline".
It sounds like it starts a new line rather then ending an existing one.

<snip>
>>          for (row = 0; row < nrows; row++)
>>           {
>>                       rowptr[row] = malloc(ncols * sizeof(int));
<snip>

>>           printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
<snip>
> On my system, the pointers differ by 48 bytes, which is probably
> an indication of how much overhead when malloc allocates 8 bytes
> (sizeof (int*)).

The allocations are for 10 ints and so are very likely to be 40 bytes.

<snip>
-- 
Ben.

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


#98062

FromKeith Thompson <kst-u@mib.org>
Date2016-12-05 12:21 -0800
Message-ID<lnfum23z62.fsf@kst-u.example.com>
In reply to#98041
Ben Bacarisse <ben.usenet@bsb.me.uk> writes:
> Keith Thompson <kst-u@mib.org> writes:
>> Alla _ <modelling.data@gmail.com> writes:
[...]
>>>           printf(" %d",(int)(rowptr[row] - rowptr[row-1]));
> <snip>
>> On my system, the pointers differ by 48 bytes, which is probably
>> an indication of how much overhead when malloc allocates 8 bytes
>> (sizeof (int*)).
>
> The allocations are for 10 ints and so are very likely to be 40 bytes.
>
> <snip>

Right, my mistake.

-- 
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]


#98032

From"James R. Kuyper" <jameskuyper@verizon.net>
Date2016-12-05 12:50 -0500
Message-ID<ec7b4b30-c869-36b1-004e-58374190b325@verizon.net>
In reply to#98017
On 12/05/2016 10:45 AM, Alla _ wrote:
>
> Hello!
>
> Please, take a look at my reading of the program (in comments to each statement)
> that uses pointers to two-dimensional  arrays. Is my understanding correct, i.e. do
> correctly interpret the given code? And, please, help me to understand one part closer
> to the end of the program.

I see that Richard Heathfield and Keith Thompson have already posted 
their responses while I was still writing mine. Oddly enough, the points 
they addressed, while all valid, are substantially different from the 
ones I chose to address. I recommend paying close attention to all three 
responses.

> #include <stdio.h>
> #include <stdlib.h>

#include <stdint.h>

<stdint.h> is new in C99. In C90, a pointer could be reversibly 
converted to an integer type, if that type had sufficient range, but it 
was optional whether or not there was any such type. The best you  could 
do was use unsigned long, and hope it was big enough. In C99, there are 
typedefs for signed and unsigned integer types guaranteed to be 
sufficiently big to reversibly store a pointer value. Such types are 
still optional, but the following macro should be #defined in <stdint.h> 
ONLY if the corresponding type is supported:

#ifndef UINTPRT_MAX
     #error uintptr_t not supported
#endif

>       int main(void)
>     {
>        // define the number of rows and columns
>               int nrows = 5;
>               int ncols = 10;
>               int row;
>
>       // initialise a pointer, which points to a pointer, which, in turn, points to type int,
>       // i.e. stores the address of an integer value
>               int **rowptr;
>
>   /*** define rowptr pointer by assigning to it the value of the address of the array,
>          allocated by the call to malloc for nrows (5 in this case) pointers to type int;
>          therefore the value of the rowptr after the call to malloc will be the address,
>          at which the first element in the array of pointers to integer type could be stored;
>           of course, none of these pointers yet point anywhere
>   ***/
>
>               rowptr = malloc(nrows * sizeof(int *));
>
>         /** check of the memory has been allocated; if not, print the info message,
>             and exit **/
>          if (rowptr == NULL)
>          {
>                     puts("\nFailure to allocate room for row pointers.\n");
>                    exit(0);
>          }
>
>         // Print the title
>          printf("\n\n\nIndex Pointer(hex) Pointer(dec) Diff.(dec)");
>
>          /** Allocate memory for an array of ncols integers for every row, and store the value of the
>              allocated address of the first element of each array at the pointer rowptr[row],
>              such that rowptr[row] now points to corresponding address of the first element
>              in the array of ncols integers **/
>
>          for (row = 0; row < nrows; row++)
>           {
>                       rowptr[row] = malloc(ncols * sizeof(int));
>
>                    /** check of the memory has been allocated; if not, print the info message,
>                      and exit **/
>                      if (rowptr[row] == NULL)
>                     {
>                                  printf("\nFailure to allocate for row[%d]\n",row);
>                                  exit(0);
>                     }

                       uintptr_t uiptr = (uintptr_t)(void*)rowptr[row];

The standard guarantees that if uintptr_t is supported, the conversion 
will be safe, and that (void*)uiptr == (void*)rowptr[row]. (7.20.1.4p1) 
This implies that uiptr contains at least as much information as 
rowptr[row].
However, the standard says nothing about what the value of uiptr 
actually means. The result is implementation-defined (6.3.2.3p6), so 
documentation is mandatory. It's a reasonable assumption that it 
corresponds in some fashion to the machine address - but I'd recommend 
checking that documentation before doing anything that relies upon that 
assumption.

>
>           /** Here is the difficult part: print the number of the current row "row",
>                 print the hexadecimal address of the pointer that now has the value

Note: the %p format specifier prints pointers in an 
implementation-defined manner. There's a good chance that it's 
hexadecimal, but that's not required. Any reasonable implementor of the 
C standard library will print it in a format that's convenient for the 
target platform - which might NOT be hexadecimal; if so, it's probably 
better (for some purposes) than a hexadecimal format.

>                 of the address of the first element of the array of integers;
>                 and the third element should the same address of the pointer
>                 but its decimal value;
>
>                 When I tried to compile this, I have received an error message,
>          which I solved by casting (void *) to the first call to rowptr[row]
>          (see my new printf below the original one), which is specified
>          by %p; but I can't solve the second error message (see below)
>          and I don't understand why the author has not mentioned anything
>          about it:
>          error: format specifies type 'int' but the argument has
>          type 'int *' [-Werror,-Wformat]
>          printf("\n%d %p %d", row, rowptr[row], rowptr[row]);
>                          ~~                     ^~~~~~~~~~~
>
>          **/
>
>                /** original printf function:
>                    printf("\n%d %p %d", row, rowptr[row], rowptr[row]);  **/
>
>                // partially corrected printf
>                  printf("\n%d %p %d", row, (void *)rowptr[row], rowptr[row]);
>

printf("\n%d %p %jx %ju\n", (void*)rowptr[row], uiptr, uiptr);

This printf() call prints the pointer in three different formats: the 
one that the implementor thought was most appropriate, hexadecimal, and 
decimal. 'j' is the length modifier for [u]intptr_t.

Note that the 'j' length modifier is new in C99. In C90, the best you 
could do was hope that unsigned long was long enough, and use the 'l' 
length modifier to print it.

>                /** print the difference between the value of addresses of each row **/
>
>                   if (row > 0)
>                              printf(" %d",(int)(rowptr[row] - rowptr[row-1]));

rowptr[row] and rowptr[row-1] are the result of two different calls to 
malloc(). Subtraction of pointers has undefined behavior unless they 
both point into or one past the end of the same array (6.5.6p9).

When subtraction of pointer has defined behavior, the result is of type 
ptrdiff_t. Even if the undefined behavior of this subtraction doesn't 
cause any other problems, it might produce a result that's too big to 
fit in an int. You should remove the cast, and print the result using 
the "%td" format specifier, where 't' is the length modifier for ptrdiff_t.

Note that the 't' length modifier is new in C99. In C90, the best you 
could do was assume that long was long enough, and use %ld to print it.

[toc] | [prev] | [standalone]


Page 2 of 2 — ← Prev page 1 [2]

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


csiph-web