:: Re: [DNG] Making sense of C pointer…
Forside
Slet denne besked
Besvar denne besked
Skribent: Edward Bartolo
Dato:  
Til: Rainer Weikusat
CC: dng
Emne: Re: [DNG] Making sense of C pointer syntax.
Hi and many thanks for the replies,

I can understand that a pointer being an address depends heavily on
machine architecture which means, on 32 bit machines it is 4 bytes
long and on 64 bit machines it is 8 bytes long. I also understand that
a pointer variable is essentially made of two parts as illustrated
below:

address [always allocated] ------------------> data [not allocated
automatically]

The address does depend on architecture but the data? And what else
can enter into a pointer's definition other than what I illustrated?

Compound/complex pointer definitions like data_type** U, work as
follows as far as my intellect can reason and deduce from what I
studied and from my now long experience coding.

address1[allocated] -----> address2[NOT allocated] ----->
data_type[not allocated]

My mistake was to assume in the case of data_type** U the compiler
would allocate the two addresses and link them, that is, store the
address of address2 in address1. The latter is not the case and a
coder is required to first allocate space for the 2nd address. In
fact, allocating space for void** ptr, in a sample program worked
without issues. I am attaching this sample program.

Edward

On 29/03/2016, Rainer Weikusat <rainerweikusat@???> wrote:
> Hendrik Boom <hendrik@???> writes:
>> On Tue, Mar 29, 2016 at 02:46:50PM +0100, Rainer Weikusat wrote:
>>> This is a wrong assumption and it relies on behaviour the C standard
>>> doesn't guarantee. Any pointer may be converted (it's even converted
>>> automatically as required) to a void * and back and
>>>
>>> "the result shall compare equal to the original pointer"
>>>
>>> But a pointer to a void * is an entirely different animal and no such
>>> guarantees are made for that. This will work in practice if there's only
>>> one 'machine pointer type' anyway, though. But using it is not necessary
>>> as void * is sufficient.
>>
>> Last time I looked at the C standard (which was a while ago, things may
>> have changed) function pointers were not guaranteed to be
>> interconvertable with data pointers.
>
> Indeed. I didn't remember this while writing the text.
> _______________________________________________
> Dng mailing list
> Dng@???
> https://mailinglists.dyne.org/cgi-bin/mailman/listinfo/dng
>

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

typedef enum {t_int, t_float, t_double, t_long_double} t_data;

int alloc_datum(void** datum, t_data type) {
  //if (*datum != NULL) return 2; // non null *datum
  switch (type) {
      case t_int: 
          *datum = malloc(sizeof(int));
            break;
        case t_float:
          *datum = malloc(sizeof(float));
            break;
        case t_double:
          *datum = malloc(sizeof(double));
          break;
        case t_long_double:
          *datum = malloc(sizeof(long double));
            break;            
  }


    if (datum == NULL)
      return 1; // malloc failed to allocate memory
        else return 0;
}


int main() {
  int* ii;
    long* ll;
    float* ff;
    double* dd;
    long double* dddd;

    
    void** ptr;
    ptr = malloc(sizeof(void*));

    
    
    alloc_datum(ptr, t_int);
    ii = *ptr;
    *ii = 10;
    alloc_datum(ptr, t_float);
    ff = *ptr;
    *ff = 5.97E24;
    alloc_datum(ptr, t_double);
    dd = *ptr;
    *dd = 2E30;
    alloc_datum(ptr, t_long_double);
    dddd = *ptr;
    *dddd = 1.5E299;
    free(ptr);

    
    printf("*11 is %d\n", *ii);
    printf("*ff is %e\n", *ff);
    printf("*dd is %e\n", *dd);
    printf("*dddd is %Le\n", *dddd);

    
    free(ii);
    free(ff);
    free(dd);
    free(dddd);


return 0;
}