Very.
When allocating space for a struct you generally (in my knowledge) don't need to calloc is, just malloc.
*edit*
include stdlib.h and remove the cast.
Very.
When allocating space for a struct you generally (in my knowledge) don't need to calloc is, just malloc.
*edit*
include stdlib.h and remove the cast.
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
Compilation is not dependent on correct memory allocation - that's why we see run time memory errors.
Borland Windows compiler doesn't like a cast'less malloc:
fails with:Code:my_parent = malloc(sizeof(parent));
stdlib is included.Code:Error E2034 struct.c 12: Cannot convert 'void *' to 'parent *' in function main()
Maybe this?C doesn't automatically typedef structs.Code:my_parent = malloc(sizeof *my_parent);
7. It is easier to write an incorrect program than understand a correct one.
40. There are two ways to write error-free programs; only the third one works.*
doesn't like that either:
Code:Error E2108 struct.c 12: Improper use of typedef 'parent' in function main() Error E2109 struct.c 12: Not an allowed type in function main() Error E2034 struct.c 12: Cannot convert 'void *' to 'parent *' in function main()
http://www.cs.toronto.edu/~heap/270F02/node31.html
Should be the following according to the above link:
Code:my_parent = (struct parent *)malloc(sizeof(struct parent));
> Error E2034 struct.c 12: Cannot convert 'void *' to 'parent *' in function
Well stop using a C++ compiler to compile C code then.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Some compilers do actually give warnings about this sort of thing (eg a variable used without being initialised), particularly if you turn on maximum warning levels. However, there is no requirement for a compiler to do that.Originally Posted by sand_man
It's not that strange that the code compiles without a hiccup, and bombs when run.
The C standard states (with a few exceptions, such as static variables) that the value of anything which has not been explictly initialised is implementation dependent. That means that a compiler is allowed to put any value into a variable that you don't initialise, and also means the compiler is not required to complain in the process. Then couple that with the fact that dereferencing ANY pointer yields undefined behaviour unless that pointer points at a valid object: the reason that is undefined behaviour is that, in some cases, it is technically impossible for a compiler to detect that an invalid pointer is being dereferenced, let alone do anything about it.
Fair enough Salem but I've got a load of win32 code in my app :/
Can I just get something really clear with reference to my previous lump of code:
Is there any problem pointing two char pointers at the same memory like the code above is doing (as long a dereferencing is handled correctly)?Code:struct base { char *string; }; struct parent { struct base my_base; }; int main() { struct parent *my_parent; char *temp_string; temp_string = (char*)malloc(21 * sizeof(char)); //strcpy(temp_string,"temp string for test"); my_parent->my_base.string = temp_string; //is this ok strcpy(temp_string,"temp string for test"); printf("String = %s\n",my_parent->my_base.string); return 0; }
Thanks again with your responses on this.
Yes it is legal to have 2 pointers point to the same memory location. And it's no problem as long as you are not trying to call free twice on the same memory location.
Btw you still haven't allocated space for my_parent.
Your code should be:
Code:struct base { char *string; }; struct parent { struct base my_base; }; int main() { struct parent *my_parent; char *temp_string; temp_string = (char*)malloc(21 * sizeof(char)); my_parent = (struct parent *)malloc(sizeof(struct parent)); my_parent->my_base.string = temp_string; //is this ok strcpy(temp_string,"temp string for test"); printf("String = %s\n",my_parent->my_base.string); free(my_parent->my_base.string); // don't free temp_string it's just an alias for my_parent->my_base.string free(my_parent); return 0; }
Kurt
Thanks Kurt.
> Fair enough Salem but I've got a load of win32 code in my app :/
And your point is what?
Last time I checked, the win32 API was a 'C' API, so what's your reason for C++?
Perhaps you should consider using new/delete for memory allocation, and using say std::string for all those strings (instead of roll-your-own char* variables with malloc).
Because all this "mixed language C/C++" approach and pointer aliasing is heading for a big disaster IMO.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.
Yeah that really bugged me when I used MSVC. I don't see why you should even be allowed to mix languages. BS would be sobbing. C++ is backwards compatible with C, but I'd still rather have a compiler that makes me stick to one or the other.Originally Posted by Salem
Good class architecture is not like a Swiss Army Knife; it should be more like a well balanced throwing knife.
- Mike McShaffry
alright :/
> C++ is backwards compatible with C
No it isn't.
It's a common misconception that C++ is a superset of C, it isn't.
http://david.tribble.com/text/cdiffs.htm
There's stuff in C which simply doesn't work in C++, and stuff which works differently in C++.
Simply compiling C code as C++ will cause you grief eventually.
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut.
If at first you don't succeed, try writing your phone number on the exam paper.