:: Re: [DNG] Making sense of C pointer…
トップ ページ
このメッセージを削除
このメッセージに返信
著者: karl
日付:  
To: dng
題目: Re: [DNG] Making sense of C pointer syntax.
Edward Bartolo:
...
> I am attaching two short C programs that I created and which I tested
> to work although the mechanism by which they work is still somewhat
> hazy to me.

...

Some comments on test101.c
====
#include <stdio.h>

void change_value(void* ptr) {
*((int*) ptr) = 20000000;
}

int main() {
  int p = 8;
  printf("p = %d\n", p);
  change_value(&p);
    printf("p = %d\n", p);

    
    return 0;
}
====
The definition "void change_value(void* ptr);" doesn't preclude the
use
 double dd;
 change_value(&dd);


You don't handle things other than int's, so don't invite the
user of change_value() to use anything else, why the "void *ptr"
(it only gives you headaches with casts) ?

You'd be better off writing it as:

void change_value(int* ptr) {
*ptr = 20000000;
}

Don't use single letter variables unless you have a as short scope
as you have in your main(). Using pp instead of p makes it much easier
to find in a simple editor or with grep, or with your own eyes.

With pointers, you have to handle the special case of null pointers.
I'm assuming you are omitting it here for brevity, but generally
change_value() should be something like:

void change_value(int* ptr) {
if (!ptr) return;
*ptr = 20000000;
}

since the func. is defined as "void change_value(int* ptr);", and
generally, users shouldn't be required to read the function body to
realize that the null pointer is forbidden.

///

Some comments on test102.c
===
#include <stdio.h>
#include <stdlib.h>

void change_value(void** ptr) {
  int* i = (int*) malloc(sizeof(int));
    *i = 10001002;
  *ptr = i;
}


int main() {
  int* p;
  //printf("p = %d\n", p);
  change_value((void**) &p);
    printf("p = %d\n", *p);
    free(p);

    
    return 0;
}
===
Same comments as for test101.c, plus:


If you use

void change_value(int ** ptr) {}

instead, your call in main() will simplify to

change_value(&p); /* instead of change_value((void**) &p); */

as you don't need the cast any longer (you didn't need it for the void
case either, but your compiler might have complained).
It will also simplify (ignoring null pointers for the moment) the body
to

void change_value(int ** ptr) {
* ptr = (int *) malloc(sizeof(int));
** ptr = 10001002;
}


malloc() inside a function and free() outside it invites to memory
leaks, don't do that to yourself. Something like

void *mem = malloc(...);
func_call(...);
free(mem);

is way more easy to debug. Yes, that doesn't map wery good to your
example, but you might benefit from rethinking how you use malloc/free.

///

Regards,
/Karl Hammar

-----------------------------------------------------------------------
Aspö Data
Lilla Aspö 148
S-742 94 Östhammar
Sweden
+46 173 140 57