2D array causing memory leak

MaxLos

Member
^^Title, I have a 2d array whose values are being updated in the Step Event and it's causing a memory leak. The project was ported over from GMS 1.x and it was working fine, I know they made some updates to arrays in 2.3 so maybe that's causing the problem? I'm not sure.

Code:
settings[0, 1] = string(global.resolution) + "x";
settings[1, 1] = string(round(global.music_volume * 100)) + "%";
settings[2, 1] = string(round(global.sfx_volume * 100)) + "%";
Top graph is without those lines of code, bottom is with

I didn't even know 2d arrays could cause memory leaks.. Is it somehow creating the array multiple times, instead of just updating its values?
 
All arrays are 1D now so I'm not sure why those are even working. You need to use arrays of arrays now.
This is correct. The new syntax for what you would previously do for 2D arrays is:
GML:
settings[0][1] = string(global.resolution) + "x";
settings[1][1] = string(round(global.music_volume * 100)) + "%";
settings[2][1] = string(round(global.sfx_volume * 100)) + "%";
 

Yal

🐧 *penguin noises*
GMC Elder
My guess would be that this is caused by the strings being leaked, not the arrays themselves (since you put references into the array instead of physically storing the entire string). Might be safer to construct literal strings inline in the draw event if you're gonna change them every step anyway, those should be temporary enough that they're garbage-collected properly.
 

MaxLos

Member
My guess would be that this is caused by the strings being leaked, not the arrays themselves (since you put references into the array instead of physically storing the entire string). Might be safer to construct literal strings inline in the draw event if you're gonna change them every step anyway, those should be temporary enough that they're garbage-collected properly.
Thanks Yal, I didn't check to see if the memory leak was still there after editing them to use the new syntax, but the leak is still there as you predicted. Are you saying that I should just move those lines of code to the draw event? If so, I tried that but memory leak still persists
 

Yal

🐧 *penguin noises*
GMC Elder
What I'm saying is that your current code should be
GML:
settings[0][1] = global.resolution
settings[1][1] = round(global.music_volume * 100)
settings[2][1] = round(global.sfx_volume * 100)

and then in the draw event
GML:
draw_text(x,y,string(settings[0][1]) + "x");
draw_text(x,y,string(settings[1][1]) + "%");
draw_text(x,y,string(settings[2][1]) + "%");
(obviously with different coordinates instead of all in exactly the same place, but I have no idea how your visual code looks like right now)
 

bandman28

Member
Arrays can be handy, but they tend to leak.
I recommend using JSON, or JavaScript Object Notation, which uses ds_lists and ds_maps, which fold great into strings.
To understand these, I recommend watching this and this, as they explain how JSON works and how to use it.
JSON is leak free, and a great way to store data.
 

Yal

🐧 *penguin noises*
GMC Elder
Arrays can be handy, but they tend to leak.
I recommend using JSON, or JavaScript Object Notation, which uses ds_lists and ds_maps, which fold great into strings.
To understand these, I recommend watching this and this, as they explain how JSON works and how to use it.
JSON is leak free, and a great way to store data.
Arrays are supposed to be memory-collected, it's data structures that can leak. JSON itself isn't a GM data type, it's just a serialization format you can turn ds_maps into for saving and loading from files.
 

MaxLos

Member
What I'm saying is that your current code should be
GML:
settings[0][1] = global.resolution
settings[1][1] = round(global.music_volume * 100)
settings[2][1] = round(global.sfx_volume * 100)

and then in the draw event
GML:
draw_text(x,y,string(settings[0][1]) + "x");
draw_text(x,y,string(settings[1][1]) + "%");
draw_text(x,y,string(settings[2][1]) + "%");
(obviously with different coordinates instead of all in exactly the same place, but I have no idea how your visual code looks like right now)
Thanks again Yal! Your suggestion did the trick. Just set the arrays to be the value I want to draw then use the 'string()' function to convert them into a string, rather than setting the 2D arrays themselves to be a string.

Old code:
Code:
var settings_x = 20;
var settings_y = 50 * global.resolution;
var settings_y_space = 50 * global.resolution;
    
settings[0][1] = string(global.resolution) + "x";
settings[1][1] = string(round(global.music_volume * 100)) + "%";
settings[2][1] = string(round(global.sfx_volume * 100)) + "%";

for (var i = 0; i < 3; i ++;)
{
     //Draw Settings' Name
     draw_set_halign(fa_left);
     draw_text_outlined(settings_x, settings_y + (i * settings_y_space), c_black, c_white, settings[i][0]);
        
     //Draw Settings' Value
     draw_set_halign(fa_right);
     draw_text_outlined(global.window_width - 30, settings_y + (i * settings_y_space), c_black, c_white, settings[i][1]) 
}
Fixed Version:
Code:
var settings_x = 20;
var settings_y = 50 * global.resolution;
var settings_y_space = 50 * global.resolution;
    
settings[0][1] = global.resolution;
settings[1][1] = round(global.music_volume * 100);
settings[2][1] = round(global.sfx_volume * 100);

for (var i = 0; i < 3; i ++;)
{
     draw_set_halign(fa_left);       
     var symbol;
     if (i = 0) symbol = "x" else symbol = "%";
        
      //Draw Settings' Name
     draw_text_outlined(settings_x, settings_y + (i * settings_y_space), c_black, c_white, settings[i][0]);
        
     //Draw Settings' Value
     draw_set_halign(fa_right);
     draw_text_outlined(global.window_width - 30, settings_y + (i * settings_y_space), c_black, c_white, string(settings[i][1]) + symbol);
 }
 
Top