|
|
|||||||||
|
|||||||||
| |||||||||
|
|
|
| |||||||||
![]() |
|
|
«
Previous Thread
|
Next Thread
»
|
Thread Tools | Search this Thread | Rate Thread | Display Modes |
|
#1
|
|||
|
|||
|
Malloc an ARRAY of structures
So I search and search but it seems that very few people want to do this - which I think should be rather simple to solve arrrrgh!
Currently my program defines a structure, then declares an array of 500 of them, which I then read values into one by one later on by assigning values to new_transaction[1].amount, new_transaction[7].year etc etc... Code:
struct transaction{
int date;
int month;
int year;
float amount;
};
struct transaction new_transaction[500];
...
...
while(num_lines >= file_line){
fscanf(input_file,"%d/%d/%d %f",&new_transaction[file_line].date,&new_transaction[file_line].month,&new_transaction[file_line].year,&new_transaction[file_line].amount);
file_line++;
}
BUT! I want to only declare the array to be as big as a figure I read in from a textfile further down the program. I have tried using malloc as follows, but I can't find the syntax anywhere for an example of using malloc with an array of structs!!: Code:
struct transaction{
int date;
int month;
int year;
float amount;
};
struct transaction *new_transaction;
...
...
num_lines = 0;
while (!feof(input_file)){
num_lines++;
fgets(file_line_contents,99,input_file);
}
...
...
while(num_lines >= file_line){
new_transaction[file_line] = (struct *)malloc(sizeof(struct transaction));
fscanf(input_file,"%d/%d/%d %f",&new_transaction[file_line].date,&new_transaction[file_line].month,&new_transaction[file_line].year,&new_transaction[file_line].amount);
file_line++;
}
Any help is greatly appreciated, even if just a nod in the right direction! I'm sure there must be a simple solution but I can't see where! George |
|
#2
|
|||
|
|||
|
Thanks to anyone who looked at this...a friend on another forum managed to solve it for me thanks.
![]() |
|
#3
|
|||
|
|||
|
I hope he pointed out the syntax was type* p = malloc(n * sizeof p). In C, don't typecast malloc.
EDIT: There also seems to be confusion in your code. You have one struct pointer. Using index notation is pointless because it will be out of bounds. What you probably should have done is have a pointer to a pointer.
__________________
Need help with broken code? Your question should be like a good bug report: (1) It has the smallest number of steps to reproduce the problem you see (2) It tells us precisely what you expected to see and (3) It tells us what you saw and how it differed from what you expected. We need all three to help you. Want better answers? Tell us what you Googled for and what steps you took to answer your own question. Last edited by Oler1s : March 21st, 2007 at 06:52 AM. |
|
#4
|
||||
|
||||
|
Quote:
Nonsense! Just because you are not required to cast the return value of malloc() in C does not mean that you shouldn't. There is no harm in making your C code C++ compilable (in fact there is a significant benefit). Clifford |
|
#5
|
||||
|
||||
|
I don't see how potentially hiding the fact that you failed to prototype the function properly counts as a benefit.
Failing to include stdlib.h without a cast will draw a compiler warning. With a cast, your code is wrong. The compiler implicitly declares malloc as returning int (not a pointer), and the result is converted by the cast on that basis. This is a disaster waiting to happen on machines with different sizes for pointers and integers. > There is no harm in making your C code C++ compilable If that were the only difference between C and C++, then I might agree. But there's so much more that you might need to consider in getting your C program up to C++ standard that a few simple casts just won't solve. It's better IMO to use each language to it's strengths than to reduce both to the lowest common denominator known as c/c++ .
__________________
If you dance barefoot on the broken glass of undefined behaviour, you've got to expect the occasional cut. UK Voter? Please send a message to Incapability Brown and the rest of Zanu-Labour |
|
#6
|
||||
|
||||
|
For C and C++ compatibility, it is sometimes nescessary to resort to conditional compiler blocks (#if...#else...#endif). You should avoid malloc() in the C++ case at any rate.
__________________
Quality of responses my vary. If you pay me, I will engage my other neuron to solve your problem. |
|
#7
|
|||
|
|||
|
Why "avoid" malloc() in C++ ? Its part of the standard library, and I think you'll find many 'new' implementations calling it under the covers anyway.
|
|
#8
|
||||
|
||||
|
The fact that you have to cast the return value from malloc() to something else in C++ is sufficient reason in my book. But new/delete do supply stricter/better type'ing for the compiler to make use of and the standard does not require malloc() be "used under the covers" and in fact it does make a distinction between the free store (new/delete) and the heap (malloc/free). The two can in fact be seperate.
Becuase malloc() is required to allocate memory in such a way that it's alignment is sufficient for all conceivable data types, it can not be optimal. new can allocate strings on char boundaries for instance, allowing them to be packed without any wasted memory between them. Getting back to the casting issue, which cast operation would you use? The old C style cast is not safe in C, much less C++. Do not forget that new and delete can be overridden for some types. Using malloc() to allocate space for such an object would violate the semantics/interface contract of that object type. I might want to use your code in an environment where all strings are stored in one kind of memory and all other data in some other type (I have done this btw, flash, eeproms and some kinds of RAM have address alignment and other issues) Just because the language allows it, doesn't make it a good idea. Where the language and it's libraries do not provide implicit portability and you really do need portable code then you should be explicit about it. malloc() is part of <cstdlib> for backwards compatibility reasons only (as is the entire <cstdlib> library!). Some parts of that library are useful for writing C/C++ portable code, but not all of them, and malloc()/free() are among the interfaces that are there strictly for backwards compatibility. Using them in a C++ program is a bad idea (unless your writing the compiler and it's libraries). |
|
#9
|
||||
|
||||
|
> Why "avoid" malloc() in C++ ?
malloc doesn't call constructors (and free doesn't call destructors). Out of lazyness, the naive c/c++ programmer might just call malloc for some struct which another programmer decided to add a constructor to. The only good reason (I can think of at the moment) to call malloc in C++ is to obtain memory to be passed on to some extern "C" API which might reallocate or free that memory. Given another decade, C-style casts in C++ might just end up deprecated (some people want this). Then it will get even messier to convert malloc to C++ as the preferred C++ cast won't even be valid C. And the only good reason for casting malloc in C is if you're using some ancient pre-ANSI C89 (C'mon people, that's nearly 20 years ago) which still uses char* as the return type of malloc instead of void* |
|
#10
|
|||
|
|||
|
Quote:
Which of course slows down all string operations since they're no longer aligned. Why would you "require" programs to be slow? |
|
#11
|
||||
|
||||
|
Quote:
As I said; Quote:
Sometimes space is more valuable than time. Sometimes not. Economics and system requirements (non-volitality for instance) can lead to system designs that are not as fast as they might otherwisse be. If speed of were the only consideration, we wouldn't have hard drives, flash or eproms. We probably wouldn't bother with general purpose computing systems; prefering instead to embed all application logic in custom ASIC's or FPGA's. Last edited by jwdonahue : March 22nd, 2007 at 09:04 PM. Reason: Fixed a truncated quote. |
|
#12
|
|||
|
|||
|
So why did you use the word "require" when its "sometimes yes sometimes no"?
Require is a very strong word. |
|
#13
|
||||
|
||||
|
Can you provide a more complet quote? I recall that I mentioned the standard required malloc() to supply a pointer that is properly aligned for all possible data types. If that is what you are referring to, I said it because it's true.
|
![]() |
| Viewing: Dev Shed Forums > Programming Languages > C Programming > Malloc an ARRAY of structures |
| Thread Tools | Search this Thread |
| Display Modes | Rate This Thread |
|
|
|
|
|