openlang

getline 读出来的行是乱码,另外还有泄漏

基本卡住了。先修哪个 bug?

while (getline(&line, &linecap, fp) != -1) {
	char *name, *role, *port;

	lineno++;
	line[strcspn(line, "\r\n")] = '\0';
	if (line[0] == '#' || line[0] == '\0')
		continue;
	name = strtok(line, " \t");
	role = strtok(NULL, " \t");
	port = strtok(NULL, " \t");
	if (!name || !role) {
		fprintf(stderr, "%s:%d: expected 'name role [port]'\n",
			path, lineno);
		fclose(fp);
		return -1;
	}
	if (inv->count == inv->cap && grow(inv) != 0) {
		fclose(fp);
		return -1;
	}
	inv->hosts[inv->count].name = name;
	inv->hosts[inv->count].role = role;
	inv->hosts[inv->count].port = port ? atoi(port) : 22;
	inv->count++;
}
free(line);
fclose(fp);
return 0;

hosts.txt:

# prod inventory
web-01 web 8080
web-02 web 8080
db-01 db 5432
cache-01 cache

hosts_bad.txt:

web-01 web 8080
db-01
cache-01 cache 6379
从英语翻译查看原文

后续讨论 6

顺着彼此的依据读下去
  1. 固定链接

    先说乱码,再说泄漏。

    name、role 和 port 都是指向 line 内部 的指针。strtok 只是往那块缓冲区里塞 NUL,然后返回缓冲区内的地址。getline 读下一行时又会复用同一块缓冲区。所以每个 host 最后指向的都是同一块内存,你看到的就是最后一行留在那里的内容。如果 line 被 realloc 了就更糟,旧指针会悬空。

    每一行都需要自己的一份拷贝,写法如下。

    inv->hosts[inv->count].name = strdup(name);
    inv->hosts[inv->count].role = strdup(role);

    记得检查 NULL,释放 inventory 的时候两个都要 free。这就是生命周期的边界,line 只活一次迭代,host 字符串则和 inv 活得一样久。

    再说泄漏,提前 return -1 的路径(坏行、grow 失败)都跳过了 free(line),只有正常路径会释放它。要么每次 return 前都 free,要么用 goto done 统一到一个清理出口。

    getline 负责分配缓冲区,所以调用方拥有它。POSIX 的页面写得很清楚 https://pubs.opengroup.org/onlinepubs/9699919799/functions/getline.html

    从英语翻译查看原文

同一个问题的其他角度

  1. 悬垂指针的警告消失了,指针还在

    通过一个包装层把名字传给 C++ 库,第一版只有一行,CString::new(name).unwrap().as_ptr()。rustc 马上就警告说,临时的 CString 在语句结束时就销毁了,指针会悬垂。行,有道理。于是我把它挪进一个小函数,…

    回复 2最近活动 rustcpp
  2. 同样的 sink 调用,这一行是拷贝,下一行就是移动

    Nim 2 是按调用点决定拷贝还是移动的,不是按 proc。 同一个参数,同一个 proc。第一次调用会拷贝,因为后面还要用 a。第二次就移动了。调用点上没有任何东西告诉你是哪种。nim c --expandArc:main 会打印改写后的函数体,两…

    回复 2最近活动 nim
  3. 指向同一实例的接口引用和对象引用

    你好,我有一个放在接口后面的 CSV sink,这个 sink 创建在一个 class 类型的变量里,因为我最后需要用到 Flush 和 Rows。 有 Announce 这一行时,横幅会打印,CSV 是空的,还会遇到 error 216 或者路径乱…

    回复 1最近活动 object-pascal