[MSX-C] Q&A official thread

Page 22/57
15 | 16 | 17 | 18 | 19 | 20 | 21 | | 23 | 24 | 25 | 26 | 27

By anonymous

incognito ergo sum (116)

anonymous's picture

16-09-2015, 07:17

AxelStone wrote:

You are right, I'm still a little confusing with pointers and where * should be placed.

Yes, pointers are one of those things in C that take a while to get used to.

Basically, you have to pay attention to the type. For example:

    int x, *y;

Imagine the asterisk as if it was part of the variable name. Therefore, x contains an int, and *y also contains an int. The funny thing is that, since *y is an int, y contains the address of that int in memory:

    int x, *y;

    /*
    x = 4  ---> x is an int variable somewhere in memory (two bytes), and these bytes contain the values 04 00
    &x ---> this returns the address of variable x in memory
    y = &x ---> y now contains the address of x (y points to x)
    */

    printf("%d¥n", *y); /* This will print 4, because y points to x, and x is 4 */

    *y = 5;
    printf("%d¥n", x); /* This will print 5, because y points to x and we have changed *p, so x changes too */  

Summarizing, if x is an int (int x):

  • x contains an int value
  • &x is the memory address of variable x

And if is y a pointer to int (int *y):

  • y contains a memory address of an int variable
  • *y is the value inside that memory address

By anonymous

incognito ergo sum (116)

anonymous's picture

16-09-2015, 07:25

Pointer arithmetic gets interesting when you're dealing with arrays. I'll write more in my blog when we reach that part, but for now: arrays and pointers are equivalent. The array[x] notation is just syntactic sugar for *(array + x). This works regardless of the size of the elements:

By anonymous

incognito ergo sum (116)

anonymous's picture

16-09-2015, 07:41

Also, you can replace the members[1] code in the list with:

p = &members[1];
(*p).name = "Yuki";
(*p).age = 5;
(*p).species = "Ferret";

to achieve exactly the same result.

By AxelStone

Prophet (3094)

AxelStone's picture

16-09-2015, 08:04

JaviLM wrote:

The error you're getting is 'heap overflow'. According to the manual (page 269) possible causes are:

- Too many includes
- You declared too many automatic variables
- The program is too complex

Basically, the frontend ran out of memory. This would be a good time to split your source code in several files and compile per parts using a BAT script. I think we discussed a way to do just that a few days ago.

So it's a problem of C compiler itself, not MSX running out of memory. Very good to know it.

JaviLM wrote:

Yes, pointers are one of those things in C that take a while to get used to.

Sure, I have found a little summary: https://en.wikibooks.org/wiki/C_Programming/Pointers_and_arrays

JaviLM wrote:

Pointer arithmetic gets interesting when you're dealing with arrays. I'll write more in my blog when we reach that part, but for now: arrays and pointers are equivalent. The array[x] notation is just syntactic sugar for *(array + x). This works regardless of the size of the elements:

So it's similar in performance terms use both notations. Good, I prefer array[x], it's more easy. B-)

By anonymous

incognito ergo sum (116)

anonymous's picture

16-09-2015, 08:35

AxelStone wrote:
JaviLM wrote:

Basically, the frontend ran out of memory. This would be a good time to split your source code in several files and compile per parts using a BAT script. I think we discussed a way to do just that a few days ago.

So it's a problem of C compiler itself, not MSX running out of memory. Very good to know it.

Correct. Let's remember that we're still working on an 8-bit machine, and the compiler only uses 64KB of RAM. Big files will make it choke, so this is why it's a good idea to split big programs in several files. I like the "one .h and one .c file per function" way because it's easier to locate stuff and saves lots of time compiling.

AxelStone wrote:
JaviLM wrote:

Pointer arithmetic gets interesting when you're dealing with arrays. I'll write more in my blog when we reach that part, but for now: arrays and pointers are equivalent. The array[x] notation is just syntactic sugar for *(array + x). This works regardless of the size of the elements:

So it's similar in performance terms use both notations. Good, I prefer array[x], it's more easy. Cool

Basically, yes. I think there are a few things that can only be done via pointers, but the point is that you can use the notation that's better for you.

By Sylvester

Hero (552)

Sylvester's picture

16-09-2015, 10:26

Quote:

Correct. Let's remember that we're still working on an 8-bit machine, and the compiler only uses 64KB of RAM. Big files will make it choke, so this is why it's a good idea to split big programs in several files. I like the "one .h and one .c file per function" way because it's easier to locate stuff and saves lots of time compiling.

I was already using multiple files with header files, but I just did "msxc.bat main" . Now I used the link.bat from this thread and it now builds my program with no errors. Just have to fix some bugs now and it's finished Smile

By hit9918

Prophet (2921)

hit9918's picture

16-09-2015, 10:56

*array + i, what was wanted was *(array + i).
operator precedence things.
if (a < b && c != d), even long time C coders prefere to make panic brackets,
if ((a < b) && (c != d)), one is so quickly hit by operator precedence.

type *array;
*(array + i*sizeof(type))
is too excessive, because 
*(array + i) already does all the pointerarithmetic with sizeof(type).

adding 1 to a pointer always slides it by the sizeof the type the pointer points to.

Arrays on the stack, when you need to increase the stack, the ability of malloc has shrunk forever.
malloc can serve temporary allocation, but stack array cant serve permanent allocation, when the function returns, the array is gone, and pointers to it crash.

By PingPong

Prophet (3885)

PingPong's picture

16-09-2015, 22:45

ag0ny wrote:

Also, you can replace the members[1] code in the list with:

p = &members[1];
(*p).name = "Yuki";
(*p).age = 5;
(*p).species = "Ferret";

to achieve exactly the same result.

Ok, let's add some variation:
p->name = "Yuki";
p->age = 5;
p->species = "Ferret";

By PingPong

Prophet (3885)

PingPong's picture

16-09-2015, 22:50

hit9918 wrote:
*array + i, what was wanted was *(array + i).
operator precedence things.
if (a < b && c != d), even long time C coders prefere to make panic brackets,
if ((a < b) && (c != d)), one is so quickly hit by operator precedence.

type *array;
*(array + i*sizeof(type))
is too excessive, because 
*(array + i) already does all the pointerarithmetic with sizeof(type).

adding 1 to a pointer always slides it by the sizeof the type the pointer points to.

Arrays on the stack, when you need to increase the stack, the ability of malloc has shrunk forever.
malloc can serve temporary allocation, but stack array cant serve permanent allocation, when the function returns, the array is gone, and pointers to it crash.

The question is: how much cost the malloc on msx-c And limited cpu horsepower compared to stack allocation?
(that is merely a aritmetic operation on SP, IX or whatsoever register). an efficient malloc-ator has to find and scan some memory structures to find and return the block requested, however i am almost sure that msx-c malloc algo is somewhat far from a sophisticated algorithm.

By Grauw

Ascended (10565)

Grauw's picture

16-09-2015, 23:03

Malloc overhead is mostly a problem for short-lived objects (er, data), if you continuously de/reallocate stuff at runtime it’s going to add up quick, and will quickly fragment the heap as well if you’re not careful.

However for long-lived objects, malloc overhead is not a problem at all. In Synthesix I malloc objects dynamically as well (all the “modules” are allocated on a 16K heap), it’s fine because I do it only occasionally and they stay in memory for a long time. (I even let my malloc implementation do an excessive amount of heap integrity checks, just because I can Smile.)

But stack allocation is just a few instructions, and of course in C it’s impossible to forget to free it, which is great.

So, I think a good rule-of-thumb may be: Try to put short-lived objects on the stack, while malloc is good for long-lived ones (that can not be static).

Page 22/57
15 | 16 | 17 | 18 | 19 | 20 | 21 | | 23 | 24 | 25 | 26 | 27