|
|
Re: Out of Memory while compiling script defining 3630 element array
[Re: GPEngine]
#433127
11/24/13 23:19
11/24/13 23:19
|
Joined: Sep 2013
Posts: 504 California
GPEngine
OP
User
|
OP
User
Joined: Sep 2013
Posts: 504
California
|
Some unexpected behavior here. On your side or on mine. Probably mine  I cannot get printf to understand that x is a float of only 4-bytes. (isn't it?)
function main() {
float x = 23.69341827522281818119;
printf("\n%f", x);
printf("\n%g", x);
printf("\n%hf", x);
printf("\n%hg", x);
}
prints
float compiling............... ok
495722305.740419
4.95722e+008
495722305.740419
4.95722e+008
This adds complications to my debugging and education. I also noticed that when defining a float, it takes up 8 bytes despite sizeof(float) = 4; I think the compiler forces 8 byte alignment. Maybe this explains why I'm having so much trouble reading in a bin?
|
|
|
Re: Out of Memory while compiling script defining 3630 element array
[Re: GPEngine]
#433128
11/24/13 23:41
11/24/13 23:41
|
Joined: Sep 2013
Posts: 504 California
GPEngine
OP
User
|
OP
User
Joined: Sep 2013
Posts: 504
California
|
Since floats have burned me (I can't inspect them using printf), I'm trying var's. Whoa... var also has surprising behavior in memory.
function main() {
var x = 23.69341827522281818119;
int y = 8;
var *xp = &x;
printf("\n%08x %08x %08x %08x", *(xp), *(xp+1), *(xp+2), *(xp+3));
printf("\n%f", *(xp));
}
e0000000 4037b183 01a6e81c 00000008
23.693419
The 00000008 is where int y landed. I conclude that var is 12 bytes in memory. That's really odd. In any case, R does not let me dump a 12 byte numeric on this machine.
Error in writeBin(pc$center, binout, size = 12) :
size 12 is unknown on this machine
Last edited by GPEngine; 11/24/13 23:41.
|
|
|
Re: Out of Memory while compiling script defining 3630 element array
[Re: GPEngine]
#433139
11/25/13 05:53
11/25/13 05:53
|
Joined: Sep 2013
Posts: 504 California
GPEngine
OP
User
|
OP
User
Joined: Sep 2013
Posts: 504
California
|
Alright, I found this technique for printing the internal representation of floats. http://www.geeksforgeeks.org/how-will-you-show-memory-representation-of-c-variables/ I see that the values in memory are correct. It's just that printf with a float is undefined. It just silently prints wrong values, perhaps by eating extra bytes?. The correct method is to typecast all float inputs to double. Can I say that this is special kind of evil? Anyway, I find that with (my understanding of) your file_read technique, the last two bytes of my array do not match my data file. Is it possible you meant to suggest this, instead? int size = 121*30*sizeof(float); float* pc_1 = (float*) malloc(size+1); file_read("myvars.bin",pc_1,size +1); That is, not only alloc an extra byte, but also read an extra byte?
|
|
|
Re: Out of Memory while compiling script defining 3630 element array
[Re: GPEngine]
#433143
11/25/13 08:21
11/25/13 08:21
|
Joined: Jul 2000
Posts: 28,075 Frankfurt
jcl

Chief Engineer
|

Chief Engineer
Joined: Jul 2000
Posts: 28,075
Frankfurt
|
Ok, 3 problems at the same time  - you want to read (size) bytes from the file, not (size+1). The function adds a 0 byte at the end, therefore your array must be bigger by at least 1 byte, but not the file. - a float is always 4 bytes, and var/double is always 8 bytes. Look here: http://manual.zorro-trader.com/aarrays.htm- The %f placeholder in printf expects var/double, not float! Look here: http://manual.zorro-trader.com/printf.htmIf a C function expects a var and you pass a float instead, it's normally automatically converted and you need not bother. Not so with printf: It has no fixed variable types. So you must always pass the correct type that is expected for the placeholder. Otherwise you'll get garbage.
|
|
|
Re: Out of Memory while compiling script defining 3630 element array
[Re: jcl]
#433146
11/25/13 09:52
11/25/13 09:52
|
Joined: Jul 2000
Posts: 28,075 Frankfurt
jcl

Chief Engineer
|

Chief Engineer
Joined: Jul 2000
Posts: 28,075
Frankfurt
|
In fact it's 5 problems:
var *xp = &x; printf("\n%08x %08x %08x %08x", *(xp), *(xp+1), *(xp+2), *(xp+3));
If you add "+1" to a pointer in C, it points to the next element, not to the next byte. You needed char *xp, not var* xp, for reading bytes. And the int has nothing to do with the preceding var, so your printf call can access unallocated memory and randomly crash. You need to define a struct for putting a var and a int together.
|
|
|
Re: Out of Memory while compiling script defining 3630 element array
[Re: jcl]
#433147
11/25/13 09:57
11/25/13 09:57
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
- The %f placeholder in printf expects var/double, not float! Look here: http://manual.zorro-trader.com/printf.htmIf a C function expects a var and you pass a float instead, it's normally automatically converted and you need not bother. Not so with printf: It has no fixed variable types. So you must always pass the correct type that is expected for the placeholder. Otherwise you'll get garbage. Umm, float is automatically promoted to double in variadic arguments (just as char and short are promoted to int). At least, according to the C standard. Since variadic arguments aren't supported in Lite-C directly, but it's still there for support with external languages, I would have assumed that the compiler conforms to type promotion rules?
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
Re: Out of Memory while compiling script defining 3630 element array
[Re: jcl]
#433151
11/25/13 11:53
11/25/13 11:53
|
Joined: Apr 2007
Posts: 3,751 Canada
WretchedSid
Expert
|
Expert
Joined: Apr 2007
Posts: 3,751
Canada
|
Therefore, the correct parameter types must be always passed to variadic argument functions. But that was exactly my point! va_arg(foo, float) is undefined behaviour, because float is automatically promoted to double when passed to a variable argument, because the compiler can't deduce the right type and default argument promotion kicks in. Here is the relevant quote from the C standard (emphasis mine): 6) If the expression that denotes the called function has a type that does not include a prototype, the integer promotions are performed on each argument, and arguments that have type float are promoted to double. These are called the default argument promotions. If the number of arguments does not equal the number of parameters, the behavior is undefined. If the function is defined with a type that includes a prototype, and either the prototype ends with an ellipsis (, ...) or the types of the arguments after promotion are not compatible with the types of the parameters, the behavior is undefined. If the function is defined with a type that does not include a prototype, and the types of the arguments after promotion are not compatible with those of the parameters after promotion, the behavior is undefined, except for the following cases: [...]
(ISO C99, latest draft, §6.5.2.2) Yes, it's a stupid rule that is dragged along because K&R C didn't have support for function prototypes. With all that said, it breaks support for external languages badly. Sure, you may now argue that variadic functions are rarely used, to which I'm going to argue that they are used quite extensively when it comes to scripting languages. Can this at least be mentioned in the manual? Because other languages will expect default type promotion because not expecting is results in undefined behaviour. Edit: It won't. A real programmer does not write pc_1[i][j], but pc_1[j+121*i]. Multidimensional arrays are for pussies. I would like to confirm that! I have used multidimensional arrays in various circumstances before and I'm the biggest pussy on earth. I also very much like compiler boundary checks and faster insertion/deletions of whole rows when working with dynamically allocated ones.
Last edited by JustSid; 11/25/13 15:34.
Shitlord by trade and passion. Graphics programmer at Laminar Research. I write blog posts at feresignum.com
|
|
|
|