different malloc + realloc then example from internet

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
cborn
Well known member
Posts: 316
Joined: Tue Oct 06, 2020 7:45 pm

different malloc + realloc then example from internet

Post by cborn »

Hello
trying to accomplish a growing string i tried this example

https://en.cppreference.com/w/c/memory/realloc
but i dont get the correct result (given as possible result)

Code: Select all

New location: 0x144c010. Size: 8 ints (32 bytes).
Old location: 0x144c010. Size: 10 ints (40 bytes).
New location: 0x144c450. Size: 12 ints (48 bytes).
Old location: 0x144c450. Size: 512 ints (2048 bytes).
Old location: 0x144c450. Size: 32768 ints (131072 bytes).
New location: 0x7f490c5bd010. Size: 65536 ints (262144 bytes).
Old location: 0x7f490c5bd010. Size: 32768 ints (131072 bytes).

Code: Select all

#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void print_storage_info(const int* next, const int* prev, int ints)
{
    if (next)
        printf("%s location: %p. Size: %d ints (%ld bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
    else
        printf("Allocation failed.\n");
}
 
int main(void)
{
    const int pattern[] = {1, 2, 3, 4, 5, 6, 7, 8};
    const int pattern_size = sizeof pattern / sizeof(int);
    int *next = NULL, *prev = NULL;
 
    if ((next = (int*)malloc(pattern_size * sizeof *next))) // allocates an array
    {
        memcpy(next, pattern, sizeof pattern); // fills the array
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
 
    // Reallocate in cycle using the following values as a new storage size.
    const int realloc_size[] = {10, 12, 512, 32768, 65536, 32768};
 
    for (int i = 0; i != sizeof realloc_size / sizeof(int); ++i)
    {
        if ((next = (int*)realloc(prev = next, realloc_size[i] * sizeof(int))))
        {
            print_storage_info(next, prev, realloc_size[i]);
            assert(!memcmp(next, pattern, sizeof pattern));  // is pattern held
        }
        else // if realloc failed, the original pointer needs to be freed
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
 
    free(next); // finally, frees the storage
    return EXIT_SUCCESS;
}
realloc_examp.png

addaptions help a little since the example is 32 or 64 bits result

const int pattern[] = {1, 2, 3 , 4};

const int realloc_size[] = {10, 12, 512};

realloc_003.png
the sizes created by zcc are enourmous and obviously wrong
what library do i need for a correct handeling?
my aim is *char, but thats for later
the original gives 'new' AND 'old' remarks
the zcc version only the 'new' remarks , in both zcc exapmples the size of eg '10' is equal
You do not have the required permissions to view the files attached to this post.
User avatar
dom
Well known member
Posts: 2174
Joined: Sun Jul 15, 2007 10:01 pm

Re: different malloc + realloc then example from internet

Post by dom »

Code: Select all

        printf("%s location: %p. Size: %d ints (%ld bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
Specifically the last argument is an int, so the format needs to be %d or random values will be picked up from the stack.
cborn
Well known member
Posts: 316
Joined: Tue Oct 06, 2020 7:45 pm

Re: different malloc + realloc then example from internet

Post by cborn »

thanks,
cutting out the 'long' off an 8bit oriented machine does help.
%ld > %d
another one that was obvious by warnings is

Code: Select all

try-C/DEF_entry$ zcc +zx -vn -lm realloc_005.c -orealloc_005 -DAMALLOC -lndos -create-app
realloc_005.c:40:58: warning: Value is out of range for assignment [-Wlimited-range]
a little adaptation was helping

Code: Select all

    // Reallocate in cycle using the following values as a new storage size.
    const int realloc_size[] = {10, 12, 512, 32768, /*65536*/ 65535, 32768};
now the result values are correct
realloc_005.png
still no 'prev' notations, what does the code want ??




Code: Select all

// https://en.cppreference.com/w/c/memory/realloc

/*
realloc_005
zcc +zx -vn -lm realloc_005.c -orealloc_005 -DAMALLOC -lndos -create-app
 --list --c-code-in-asm     -Cz --noloader
*/


#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
 
void print_storage_info(const int* next, const int* prev, int ints)
{
    if (next)
        printf("%s location: %p. Size: %d ints (%d bytes).\n",
               (next != prev ? "New" : "Old"), (void*)next, ints, ints * sizeof(int));
    else
        printf("Allocation failed.\n");
}
 
int main(void)
{
    const int pattern[] = {1, 2, 3, 4, 5, 6, 7, 8};
    const int pattern_size = sizeof pattern / sizeof(int);
    int *next = NULL, *prev = NULL;
 
    if ((next = (int*)malloc(pattern_size * sizeof *next))) // allocates an array
    {
        memcpy(next, pattern, sizeof pattern); // fills the array
        print_storage_info(next, prev, pattern_size);
    }
    else
        return EXIT_FAILURE;
 
    // Reallocate in cycle using the following values as a new storage size.
    const int realloc_size[] = {10, 12, 512, 32768, /*65536*/ 65535, 32768};
 
    for (int i = 0; i != sizeof realloc_size / sizeof(int); ++i)
    {
        if ((next = (int*)realloc(prev = next, realloc_size[i] * sizeof(int))))
        {
            print_storage_info(next, prev, realloc_size[i]);
            assert(!memcmp(next, pattern, sizeof pattern));  // is pattern held
        }
        else // if realloc failed, the original pointer needs to be freed
        {
            free(prev);
            return EXIT_FAILURE;
        }
    }
 
    free(next); // finally, frees the storage
    return EXIT_SUCCESS;
}
You do not have the required permissions to view the files attached to this post.
User avatar
dom
Well known member
Posts: 2174
Joined: Sun Jul 15, 2007 10:01 pm

Re: different malloc + realloc then example from internet

Post by dom »

There's two different ways of implementing realloc:

1. Always allocate a new block
2. Attempt to grow the existing block by coalescing a free block afterwards

You can see from the addresses printed that the classic realloc starts handing out blocks at the end of the heap space. This means it can't use method 2, so has to use method 1 so you'll never get an "old" log.

The newlib malloc implements method 2, but that causes some interesting performance issues: https://github.com/z88dk/z88dk/issues/1 ... -287221881
Timmy
Well known member
Posts: 405
Joined: Sat Mar 10, 2012 4:18 pm

Re: different malloc + realloc then example from internet

Post by Timmy »

dom wrote: Sat Jun 15, 2024 11:53 pm There's two different ways of implementing realloc:

1. Always allocate a new block
2. Attempt to grow the existing block by coalescing a free block afterwards
This is why, in my sp1 related games, I always allocate a new block and never return blocks back to the computer.

Of course that means I never use realloc at all, just malloc and free. You can see this in the original version of my sp1 example, where malloc and free still had their original definitions.

Not returning allocated blocks sounds awful if you have different sprites every time, but if all your sp1 sprites are made of the same size, you can just re-use the same allocated memory blocks. So, in practice, it is not a big deal.
cborn
Well known member
Posts: 316
Joined: Tue Oct 06, 2020 7:45 pm

Re: different malloc + realloc then example from internet

Post by cborn »

This memory block will grow 7 bytes every new found variable, its sure that it has 1 block of 7 bytes "..DEFFN" and after that "..12345" in the 1+4 mantisse from zx basic. a def fn can have 2x 26 internal variables, i did not try in reality. that leads to 53 blocks of 7 bytes. leading to a minimum of 1x7 bytes upto a maximum is 371 bytes from which usualy 1 - 5 x 7 = 35 will be used. so a growing alloction is probably better to save space.
the '..' are variable names "a " and "a$" etc.
@Timmy where can i find your sp1 example ?
stefano
Well known member
Posts: 2202
Joined: Mon Jul 16, 2007 7:39 pm

Re: different malloc + realloc then example from internet

Post by stefano »

In the nineties I never thought I'd have seen memory leak issues on a Spectrum
Timmy
Well known member
Posts: 405
Joined: Sat Mar 10, 2012 4:18 pm

Re: different malloc + realloc then example from internet

Post by Timmy »

cborn wrote: Sun Jun 16, 2024 11:59 am @Timmy where can i find your sp1 example ?
The old version of the sp1 example with u_malloc and u_free is here: https://worldofspectrum.org/forums/disc ... ith-source

The "new" version is here: https://github.com/z88dk/z88dk/tree/mas ... _sp1/demo2 or in your z88dk distribution.
fraespre
Member
Posts: 57
Joined: Mon Aug 19, 2019 8:08 pm

Re: different malloc + realloc then example from internet

Post by fraespre »

Timmy wrote: Sun Jun 16, 2024 12:52 pm The old version of the sp1 example with u_malloc and u_free is here: https://worldofspectrum.org/forums/disc ... ith-source
The "new" version is here: https://github.com/z88dk/z88dk/tree/mas ... _sp1/demo2 or in your z88dk distribution.
It would be easy to make the "new" version of sp1 use fixed memory, instead of dynamic memory. And thus avoid the malloc library
cborn
Well known member
Posts: 316
Joined: Tue Oct 06, 2020 7:45 pm

Re: different malloc + realloc then example from internet

Post by cborn »

Timmy wrote: Sun Jun 16, 2024 12:52 pm
cborn wrote: Sun Jun 16, 2024 11:59 am @Timmy where can i find your sp1 example ?
The old version of the sp1 example with u_malloc and u_free is here: https://worldofspectrum.org/forums/disc ... ith-source

The "new" version is here: https://github.com/z88dk/z88dk/tree/mas ... _sp1/demo2 or in your z88dk distribution.
Did a
zcc +zx -vn -O3 -startup=31 -clib=new demo.c graphics.asm -o demo1 -create-app
zcc +zx -vn -SO3 -startup=31 -clib=sdcc_iy --max-allocs-per-node200000 demo.c graphics.asm -o demo2 -create-app
for both the compiler and appmake in 1 go

now i wonder if the malloc is integreted into sp1 since i dont see the instruction in the code
it has a preset, but it dont see the actual command
zcc .... --max-allocs-per-node200000
#include <malloc.h>
#pragma output CLIB_MALLOC_HEAP_SIZE = 3000 // create a 3000-byte heap in BSS section
cborn
Well known member
Posts: 316
Joined: Tue Oct 06, 2020 7:45 pm

Re: different malloc + realloc then example from internet

Post by cborn »

Hi
sorry but this example is wrong
i overlooked a importend part on the page
setting the correct compiler BEHIND the screen
https://en.cppreference.com/w/c/memory/realloc

de EXAMPLE part has severall choices and one of that is C89 style
any "run" with an 'c89' will FAIL
pitty, but now i know that i dont have to look further for this realocation routine
cheers
cborn
Well known member
Posts: 316
Joined: Tue Oct 06, 2020 7:45 pm

Re: different malloc + realloc then example from internet

Post by cborn »

Hi
my last test does not work
although it has no error message :-)


with the REALLOC i expected a bigger value, but , nope

sizeof (*a) * 2 should make 'a' twice bigger ??

common question, what do i mis here ??

Code: Select all


/*
copycalloc002
zcc +zx -vn -lm copycalloc002.c -ocopycalloc002 -DAMALLOC1  -lndos -create-app
 --list --c-code-in-asm     -Cz --noloader
*/


//https://stackoverflow.com/questions/2259890/using-sizeof-on-mallocd-memory
//char (*s)[100] = malloc( sizeof( char[100] ) );
//printf( "%u byte pointer to %u bytes of size %u elements\n",sizeof s, sizeof *s, sizeof **s );


#include <stdio.h>
#include <stdlib.h>
#include "spectrum.h"
#include <string.h>
//#include <malloc.h>



void main(){

zx_cls();

unsigned char (*a)[8] = calloc(1, sizeof(unsigned char[8] ) );
unsigned char (*b)[8] = calloc(1, sizeof(unsigned char[8] ) );
char def[8]="__DEFFN";

   printf("-%s-  %d\n",def,sizeof def);
   printf("0-a %d a %d b %d def %d\n", sizeof *a ,sizeof **a, sizeof *b, sizeof def );
   printf("0-a -%s- b -%s- -%s-\n", a ,b , def);

   memcpy(a,def,sizeof def);
   memcpy(b,a,sizeof *a);

   memcpy(b[1],"1",1);
//   strcpy(b[0],"0");

//   b[1]="1" ; lvalue ??

   printf("1-a %d a %d b %d\n", sizeof *a ,sizeof **a, sizeof *b );
   printf("1-a -%s- b -%s-\n", a ,b );

   a= realloc(2, sizeof *a );

   printf("2-a %d a %d b %d\n", sizeof *a ,sizeof **a, sizeof *b );
   printf("2-a -%s- b -%s-\n", a ,b );

   memcpy(a,b,sizeof *b);

   printf("3-a %d a %d b %d\n", sizeof *a ,sizeof **a, sizeof *b );
   printf("3-a -%s- b -%s-\n", a ,b );

   a= realloc(1, sizeof *a *2 );

   printf("4-a %d a %d b %d\n", sizeof *a ,sizeof **a, sizeof *b );
   printf("4-a -%s- b -%s-\n", a ,b );

   strcpy(b[9],def);
   memcpy(a,b,sizeof *b);

   printf("5-a %d a %d b %d\n", sizeof *a ,sizeof **a, sizeof *b );
   printf("5-a -%s- b -%s-\n", a ,b );

free(a);
free(b);
free(def);

return 0;
}
You do not have the required permissions to view the files attached to this post.
Post Reply