-1

I am using good old Borland's TurboC compiler for DOS. When I use malloc() on compact memory model and write anything to the allocated memory, program freezes at some point (I suspect malloc() returns pointer to somewhere I shouldn't write). When I do the same on small memory model, it works fine.

I took a look on the allocated memory and the pointer the malloc() returns, using this small piece of code:

#include <stdio.h>

unsigned char *x;
unsigned int i;
unsigned int mds, mss;

#define X(a) x[i+(a)]

int main(void) {

    // show current SS and DS
    asm {
        mov AX, DS
        mov mds, AX
        mov AX, SS
        mov mss, AX
    }
    printf("ds=%04x, ss=%04x\n", mds, mss);

    // allocate memory and show the pointer
    x = (unsigned char*)malloc(128);
    printf("x=%p\n", x);

    // write out contents of the allocated memory
    for (i = 0; i < 128; i += 16)
        printf("%p: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", &x[i], X(0), X(1), X(2), X(3), X(4), X(5), X(6), X(7), X(8), X(9), X(10), X(11), X(12), X(13), X(14), X(15));

    free(x);
    return 0;
}

When I compile this for small memory model, I get:

tcc -ms -IC:\turboc\include -LC:\turboc\lib -etest.exe test.c

ds=02f9, ss=02f9
x=05f2
05f2: 00 00 00 ... 00
0602: 00 00 00 ... 00
...
0662: 00 00 00 ... 00

When I do the same with compact memory model, I get:

tcc -mc -IC:\turboc\include -LC:\turboc\lib -etest.exe test.c

ds=034f, ss=0391
x=0000:0004
0000:0004: 08 00 70 00 ... 08 00 70 00
0000:0014: 54 ff 00 f0 ... a5 fe 00 f0
...
0000:0074: a4 f0 00 f0 ... 60 14 00 f0

The pointer 0000:0004 looks suspicious to me and I suspect it to point somewhere outside the heap. I do not recognize the contents, but if I write to the memory, the program freezes.

What am I doing wrong and what should I do to get correct pointer from malloc()? Any suggestion will be appreciated.

Michael Petch
  • 46,082
  • 8
  • 107
  • 198
Roman Hocke
  • 4,137
  • 1
  • 20
  • 34
  • 2
    "Good old DOS", eh? I'll agree with you about the "old", anyway... :-) – Steve Summit Jun 17 '18 at 14:32
  • You really don't need that `X()` macro, you know. – Steve Summit Jun 17 '18 at 14:35
  • Don't use TurboC, and don't use MSDOS unless you are forced to. Consider installing some free operating system (e.g. some [linux distribution](https://en.wikipedia.org/wiki/Linux_distribution)...) on your PC, even if it is an old one. Use some standard conforming C compiler (at least for [C99](https://en.wikipedia.org/wiki/C99)...). You surely have more than [640K](https://quoteinvestigator.com/2011/09/08/640k-enough/) of memory these days, so install an OS and compiler taking advantage of them – Basile Starynkevitch Jun 17 '18 at 16:13
  • 1
    If you are interested in [retrocomputing](https://retrocomputing.stackexchange.com/), use that forum for such questions – Basile Starynkevitch Jun 17 '18 at 16:19
  • I'm voting to close this question as off-topic because this question is obsolete (or should be asked on [retrocomputing](https://retrocomputing.stackexchange.com/)) – Basile Starynkevitch Jun 17 '18 at 16:21
  • @BasileStarynkevitch: Thank You for pointing me to retrocomputing, did not know that site. I do it for fun. – Roman Hocke Jun 17 '18 at 16:28
  • 3
    Feel free to ask programming related questions here. Despite Basile Starynkevitch's comments, there's no rule against asking questions related to obsolete technologies. – Ross Ridge Jun 18 '18 at 07:15
  • 2
    @RossRidge : Glad I'm not the only one that thought that. – Michael Petch Jun 19 '18 at 01:17
  • 2
    This bug is older than DOS, however... missing stdlib.h. It's a very well-known flaw in the long since obsolete C90 standard. You should start to smell a rat when different memory model -> different pointer size. In small memory model the pointers were likely 16 bit just like `int`. When pointers got bigger than the size of an `int`, the compiler went bananas. – Lundin Sep 16 '19 at 07:01

2 Answers2

4

According to an old reference manual, including <stdlib.h> should fix this. (Compilers on other systems would print a warning for this code, too.)

Without a prototype, malloc is implicitly declared as returning int. The returned int value is automatically converted to a pointer. But in the compact memory model, pointers and ints do not have the same representation, so the implicit declaration and conversion do not yield the correct value.

Pretty much same thing happens with implicitly declared malloc on 64-bit UNIX-like platforms.

Florian Weimer
  • 32,022
  • 3
  • 48
  • 92
3

If memory serves me correctly if you want memory allocation to behave as expected with memory models that use far and huge pointers you have to include alloc.h. Try adding this to your file:

#include <alloc.h>
Michael Petch
  • 46,082
  • 8
  • 107
  • 198
  • 1
    You shall be proud of Your memory, this is the right solution, it solved my problem! Thanks a lot :-) – Roman Hocke Jun 17 '18 at 15:24
  • 2
    Just wanted to say that this saved my bacon today with uses of `farmalloc`, from a program crashing while loading to everything working, just by adding that header :D – Edu Garcia Feb 25 '22 at 14:37