I wade with memory

Hello

pub fn addListStr(self: std.ArrayList([]const u8), text : []const u8) ! std.ArrayList([]const u8){

  const allocator = std.heap.page_allocator;
  var LIST = std.ArrayList([] const u8).init(allocator);
  var iter = iteratStr.iterator(text);

  for (self.items) | val | {
    LIST.append(val) catch return ErrUtils.fld_ioField_addListStr_invalide;
  }

  while (iter.next()) |ch|  {
    LIST.append(ch) catch return ErrUtils.fld_ioField_addListStr_invalide;
    }
  self.deinit();
  return LIST;
}

a) do variables die when exiting the function.
b) in this case how to make a defer !!! because result returns a value
does defer if i put it… will it release after transmitting the value???

I ask this question because my program works but it swells visibly

I also use on arraylist
but that did not transcend
x_FIELD = std.ArrayList([] const u8).init(allocator);
ex: defer x_FIELD.clearAndFree();

please i need clarification

c) I specify, I have no global variable apart from my declaration
const allocator = std.heap.page_allocator;
maybe you shouldn’t

a) do variables die when exiting the function.

Yes.

It’s not clear what you’re trying to do, and you seem to be mixing []const u8 and u8 (one of those append calls looks like it should be a compile error).

Maybe it would be helpful to look at an example of a function that creates an ArrayList and returns a slice:

no there is no compilation error, but the example includes other functions

thank you for the answer.

non il n’y pas d’erreur de compilation, mais l’exemple comprend d’autre function

par

pub fn concatStr( a: []const u8, b: []const u8) []const u8 {
  const allocator = std.heap.page_allocator;
  const result = allocator.alloc(u8, a.len + b.len) catch unreachable;
  std.mem.copy(u8, result, a);
  std.mem.copy(u8, result[a.len..], b);
  return result;
}

pub fn listToStr( self: std.ArrayList([]const u8))  []const u8 {
  var result : []const u8 = "" ;
  for (self.items) |ch| {
    result =  concatStr(result,ch);
  }
  return result;
}


pub fn memoire() [] const u8 {
  const allocator = std.heap.page_allocator;
  var LIST0 = std.ArrayList([] const u8).init(allocator);
  defer LIST0.deinit();
  var x : u8  = 0;
  var t1 : []const u8 = "tota";
  var t2 : []const u8 = "";

    while(LIST0.capacity < t1.len) : (x += 1) {
      LIST0.append(t1[x..]) catch unreachable;
    }

    t2 = listToStr(LIST0);


    return t2;
}



pub fn main() !void {
var i : usize = 0;
const stdin = std.io.getStdIn().reader();
var buf: [10]u8 = undefined;
while (i < 50 ) : ( i += 1) {
  buf = [_]u8{0} ** 10;
  std.debug.print("{s}",.{memoire()});
  _= try stdin.readUntilDelimiterOrEof(buf[0..], '\n');
}


}

A useless example, but which shows that memory swells.

following the process
call terminal ./test at the beginning the program which 131k0 passes to 262 ko

compile:

  • zig build --build-file /home/soleil/Zterm/src-zig/buildtest.zig

BUILD DEBUG test size : 1,1M

I redid the tests without reading terminal I have no program that swells

I made a silly little program to see how the memory swells
After to see that there is no swelling just tag wcons

const std = @import("std");


pub fn concatStr( a: []const u8, b: []const u8) []const u8 {
  const allocator = std.heap.page_allocator;
  const result = allocator.alloc(u8, a.len + b.len) catch unreachable;
  defer allocator.free(result);
  std.mem.copy(u8, result, a);
  std.mem.copy(u8, result[a.len..], b);
  return std.fmt.allocPrint(allocator,"{s}",.{result},)  catch unreachable;
}

pub fn listToStr( self: std.ArrayList([]const u8))  []const u8 {
  var result : []const u8 = "" ;
  for (self.items) |ch| {
    result =  concatStr(result,ch);
  }
  return result;
}


pub fn lowerStr(str:[] const u8) [] const u8 {
  const allocator = std.heap.page_allocator;
  const result = allocator.alloc(u8, str.len ) catch unreachable;
  defer allocator.free(result);
  std.mem.copy(u8, result, str);
  var idx:usize = 0;
	while (idx < result.len) :(idx += 1 ) {
    result[idx] = std.ascii.toLower(result[idx]);
    }

	return  std.fmt.allocPrint(allocator,"{s}",.{result},)  catch unreachable;
}

pub fn memoire() [] const u8 {
  const allocator = std.heap.page_allocator;
  var LIST0 = std.ArrayList([] const u8).init(allocator);
  defer LIST0.deinit();
  var x : u8  = 0;

  var t1 : []const u8 = "TOTA";
  var t2 : []const u8 = "";

   LIST0.append(t1) catch unreachable;

    t2 = listToStr(LIST0);

    t2 = lowerStr(t2);
    return t2;
}



pub fn main() !void {

var i : usize = 0;
const stdin = std.io.getStdIn().reader();

const STDOUT_TERM = std.io.getStdOut();
var buf_Output = std.io.bufferedWriter(STDOUT_TERM.writer());
// Get the Writer interface from BufferedWriter
const wcons = buf_Output.writer();

var buf : [10]u8 = undefined;
while (i < 100 ) : ( i += 1) {
  buf = [_]u8{0} ** 10;
  wcons.print("{s}",.{memoire()}) catch unreachable;

  buf_Output.flush() catch unreachable;
  _= try stdin.readUntilDelimiterOrEof(buf[0..], '\n');

  wcons.print("\x1b[H\x1b[2J\x1b[3J", .{}) catch unreachable;

  buf_Output.flush() catch unreachable;
  _= try stdin.readUntilDelimiterOrEof(buf[0..], '\n');


}


}

I finally understood the allocator system is what blocked and swelled the memory
especially with return std.fmt.allocPrint(allocator,“{s}”,.{result},) catch unreachable;
}

or

var arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
var allocator = arena.allocator();
pub fn deinitUtils() void {
    arena.deinit();
    arena = std.heap.ArenaAllocator.init(std.heap.page_allocator);
    allocator = arena.allocator();
}

or 
allocator.free(..)  etc.

the problem is the use and in what condition it should be used.
but this is a very important part to understand when using zig-lang

we see examples but which do not correspond to real situations.

For my own edification here, help me understand what you’ve concluded. When you say “swells” do you mean that the memory was not getting deallocated?

It seemed odd that the original example was initializing the allocator in the same function (as opposed to taking the allocator in as an argument or, as in your last example, has it as a global variable). I can see how changing that would give you a better-behaved program.

Am I understanding your post correctly?

Good morning,
i work as am.
I use an allocator to allocate a fixed memory space to an area.

return std.fmt.allocPrint(allocator,"{s}",.{result},) catch unreachable;

but I am also in the middle of reviewing my code
to find a method where I would not need an allocator.
for example: burfPrintZ
example :

allocator.free(result);
var buffer: [4096] u8 = undefined;
  xfield.regex = std.fmt.bufPrintZ(buffer[0..] ,"^[0-9]{s}{d}{s}$",.{"{1,",xfield.width,"} "},) catch unreachable;
1 Like

No it’s not strange. Imagined several display modules, which has its own allocators, and also a lib with functions which also has its own allocators.
at each module exit I clean and keep the data to archive them, in Json and source code. (that’s what I’ve already done with nim-langue)
but I am preparing the principle.
despite daily work since Oct. 2022. I am still far from having understood all the subtleties.
I need to test and feel things, in order to reason ZIG-LANG.

For example:
this serving of bufPrint does not guarantee that the value is correctly assigned
while allocprint does it correctly
there I spent at least 4 days doing tests …

why I don’t guarantee the value, because it uses the same address on several bufprintz that follow. the last sets all the others to the same value.
so that justifies allocprint . …!!!