如何释放申请的内存问题? #123
Closed
zhang-chuanfeng
started this conversation in
General
Replies: 2 comments 4 replies
-
const std = @import("std");
pub fn main() !void {
var gpa = std.heap.GeneralPurposeAllocator(.{}){};
defer if (gpa.deinit() != .ok) @panic("leak");
const allocator = gpa.allocator();
const stdin = std.io.getStdIn();
var rdr = stdin.reader();
var list = std.ArrayList(u8).init(allocator);
defer list.deinit();
const wtr = list.writer();
while (rdr.streamUntilDelimiter(wtr, '\n', null)) {
if (std.mem.eql(u8, "exit", list.items)) {
return;
}
defer list.clearRetainingCapacity();
var iterator = std.mem.tokenizeAny(u8, list.items, "\t \r");
var args = std.ArrayList([]const u8).init(allocator);
defer args.deinit();
while (iterator.next()) |arg| {
try args.append(arg);
}
var cp = std.ChildProcess.init(args.items, allocator);
const term = cp.spawnAndWait();
std.debug.print("{any}\n", .{term});
} else |e| {
std.debug.print("Read stdin failed, err:{any}\n", .{e});
std.posix.exit(1);
}
}
尝试用纯 Zig 的方式来写,会简单不少,你现在的做法相当于完全 port C 的逻辑,很多 Zig 的特点没用上。 |
Beta Was this translation helpful? Give feedback.
2 replies
-
参考后修改: const std = @import("std");
fn signalHandler(sig: i32) align(1) callconv(.C) void {
std.debug.print("Received signal {}\n", .{sig});
std.os.linux.exit(-1);
}
fn signal(sig: u6, handler_fun: std.os.linux.Sigaction.handler_fn) void {
const sigAction = std.os.linux.sigaction;
var action = std.os.linux.Sigaction{ .handler = undefined, .mask = std.os.linux.empty_sigset, .flags = 0 };
action.handler.handler = handler_fun;
_ = sigAction(sig, &action, null);
}
pub fn main() !void {
signal(std.os.linux.SIG.INT, signalHandler);
std.debug.print("%% ", .{});
const allocator = std.heap.page_allocator;
const stdin = std.io.getStdIn().reader();
var pid: usize = undefined;
var status: u32 = undefined;
while (true) {
const line = try stdin.readUntilDelimiterAlloc(allocator, '\n', 1024);
pid = std.os.linux.fork();
if (pid < 0) {
std.debug.print("fork error", .{});
std.os.linux.exit(-1);
} else if (pid == 0) {
// child
const envp = [_:null]?[*:0]const u8{ "PATH=/usr/bin:/bin".ptr, null };
var tokenIter = std.mem.tokenize(u8, line, " \t\n\r");
// 使用ArrayList自动增长
var argvs = std.ArrayList([]const u8).init(allocator);
defer argvs.deinit();
while (tokenIter.next()) |token| {
try argvs.append(token);
}
// 这里参考 std.ChildProcess.spawnPosix()
// 使用allocSentinel 和 dupeZ
const argv_buf = try std.heap.page_allocator.allocSentinel(?[*:0]const u8, argvs.items.len, null);
defer std.heap.page_allocator.free(argv_buf);
for (argvs.items, 0..) |arg, i| argv_buf[i] = (try allocator.dupeZ(u8, arg)).ptr;
_ = std.os.linux.execve(argv_buf.ptr[0].?, argv_buf.ptr, &envp);
std.debug.panic("couldn't execute: {s}", .{line});
std.os.linux.exit(127);
}
pid = std.os.linux.waitpid(@intCast(pid), &status, 0);
if (pid < 0) {
std.debug.panic("waitpid fail", .{});
}
std.debug.print("%% ", .{});
}
// test execve()
// const args = [_:null]?[*:0]const u8{ "ls".ptr, "-l".ptr, "./".ptr, null };
// const envp = [_:null]?[*:0]const u8{null};
// _ = std.os.linux.execve("/usr/bin/ls".ptr, &args, &envp);
// std.os.linux.fork()
// std.time.sleep(100 * std.time.ns_per_hour);
} |
Beta Was this translation helpful? Give feedback.
2 replies
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
如下代码实现fork执行exec程序代码:中间申请的buff如何释放掉?怎么感觉写起来没这么方便,应该有更好的实现方式吧?感觉比c写的代码要繁琐
比如下面的执行结果:
c的代码实现
Beta Was this translation helpful? Give feedback.
All reactions