Computing desk | ||
---|---|---|
< October 16 | << Sep | October | Nov >> | Current desk > |
Welcome to the Wikipedia Computing Reference Desk Archives |
---|
The page you are currently viewing is an archive page. While you can leave answers for any questions shown below, please ask new questions on one of the current reference desk pages. |
A web programmer told me that the Dependency Inversion principle in OOP describes this:
In OOP design we usually go from outside (request) to the inside (response), from the view, to the model (by the controller CRUDing the model via view).
I have 2 questions regarding this:
1. Is this explanation of the principle accurate? Iא doesn't say why it specifically relates to the principle.
2. Why is "from the outer to the inner" is "inverted" in web?... I can't see why it would be inverted and not the other way around.
Anonymous.
hello, is it allowed to cast a struct A*, say, as struct B*, and vice versa, if struct B has struct A as its very first member?
I want to do something like this:
Extended content
|
---|
#include <malloc.h> struct node_ { struct node_ *next; }; struct my_int { struct node_ link; int data; }; struct my_float { struct node_ link; float data; }; struct my_int *head=NULL; struct my_float *head2=NULL; struct my_int *new_int(int a){ struct my_int *p=(struct my_int*) malloc(sizeof(struct my_int)); p->data=a; p->link.next=NULL; return p; } struct my_float *new_float(float a){ struct my_float *p=(struct my_float*) malloc(sizeof(struct my_float)); p->data=a; p->link.next=NULL; return p; } void insert(void *a, void *b){ struct node_** p=(struct node_**)a; struct node_ *q=(struct node_*)b; q->next=*p; *p=q; } int main(void){ insert(&head,new_int(17)); insert(&head,new_int(18)); insert(&head,new_int(19)); insert(&head2,new_float(3.14)); insert(&head2,new_float(17.2)); insert(&head2,new_float(19.1)); for(struct my_int *p=head;p!=NULL;p=(struct my_int*)p->link.next){ printf("%d\n",((struct my_int*)p)->data); } for(struct my_float *p=head2;p!=NULL;p=(struct my_float*)p->link.next){ printf("%f\n",((struct my_float*)p)->data); } return 0; } |
this compiles, and works, but I'm not sure it's kosher. TIA 78.50.125.206 (talk) 20:35, 17 October 2017 (UTC)
malloc()
returns a valid pointer! If p
becomes NULL
, an assignment to p->data
will most probably end with a crash. --CiaPan (talk) 20:59, 17 October 2017 (UTC)malloc()
can fail. For instance, many systems allow the available memory of a process to be limited. Of course this all depends on the problem domain. If this is just a toy program, who cares? But if this is part of a larger program, and you want to be well-behaved, always check malloc. (Personally, I think it's a good thing to do anyway. That way you develop the habit of always doing the Right Thing.) On a related note, malloc.h
is a non-standard glibc header. The standard C header containing malloc()
is stdlib.h
. (Again, fine if you want your program to depend on glibc, but I don't know if you do.) Also, you didn't include stdio.h
for printf()
. Finally, you didn't free()
what you malloc()
ed. (The same goes for this as for malloc()
.) --47.138.160.139 (talk) 22:58, 18 October 2017 (UTC)
-std=c99 -O0 -Wall -Wextra -Wpedantic
. Then fix your code to not generate warnings. This will teach you things you might have overlooked, or didn't know were Bad Things or non-standard compiler extensions. Compiler extensions are not inherently bad, but you should be aware you're relying on them. And if you're wondering about optimizations, they can obscure bugs in your code. For instance, the compiler might optimize away code containing a runtime error. --47.138.160.139 (talk) 05:31, 19 October 2017 (UTC)malloc()
. Accessing memory at NULL
will most probably end with crash in most of popular environments, but that is not guaranteed! The way of handling the unexpected situation is up to you, but it's always better to do that explicitly. You can simply return NULL
from your function and allow the caller to decide whether it wants to invoke a crash, end a process with an error status or possibly recover from the condition in some other manner. struct my_float *new_float(float a){ if( struct my_float *p=(struct my_float*) malloc(sizeof(struct my_float)) ) { p->data=a; p->link.next=NULL; return p; } return NULL; } void insert(void *a, void *b){ if( b ) { struct node_** p=(struct node_**)a; struct node_ *q=(struct node_*)b; q->next=*p; *p=q; } }