cpyobject
label与object分离共享object, 分离的好处是垃圾回收就方便。code1,/* https://www.onlinegdb.com/online_c_compiler */ #include stdio.h #include stdlib.h /* Simplified Py_ssize_t */ typedef long Py_ssize_t; /* Forward declarations */ typedef struct PyObject PyObject; typedef struct PyTypeObject PyTypeObject; /* This is similar to CPythons idea: typedef struct _object { Py_ssize_t ob_refcnt; PyTypeObject *ob_type; } PyObject; */ struct PyTypeObject { const char *tp_name; void (*tp_print)(PyObject *self); void (*tp_dealloc)(PyObject *self); }; struct PyObject { Py_ssize_t ob_refcnt; /* reference count */ PyTypeObject *ob_type; /* dynamic type information */ }; /* Concrete object types. They start with PyObject so that PyObject* can be safely cast to them. */ typedef struct { PyObject ob_base; long value; } PyIntObject; typedef struct { PyObject ob_base; double value; } PyFloatObject; /* ---------------- Printing functions ---------------- */ static void PyInt_Print(PyObject *self) { PyIntObject *obj (PyIntObject *)self; printf(%ld, obj-value); } static void PyFloat_Print(PyObject *self) { PyFloatObject *obj (PyFloatObject *)self; printf(%g, obj-value); } /* ---------------- Deallocation functions ---------------- */ static void PyInt_Dealloc(PyObject *self) { PyIntObject *obj (PyIntObject *)self; printf([gc] dealloc int object %ld\n, obj-value); free(obj); } static void PyFloat_Dealloc(PyObject *self) { PyFloatObject *obj (PyFloatObject *)self; printf([gc] dealloc float object %g\n, obj-value); free(obj); } /* ---------------- Type objects ---------------- */ static PyTypeObject PyInt_Type { int, PyInt_Print, PyInt_Dealloc }; static PyTypeObject PyFloat_Type { float, PyFloat_Print, PyFloat_Dealloc }; /* ---------------- Reference counting ---------------- */ static void Py_Incref(PyObject *obj) { if (obj) { obj-ob_refcnt; } } static void Py_Decref(PyObject *obj) { if (!obj) { return; } obj-ob_refcnt--; if (obj-ob_refcnt 0) { obj-ob_type-tp_dealloc(obj); } } /* ---------------- Object constructors ---------------- */ static PyObject *PyInt_FromLong(long value) { PyIntObject *obj malloc(sizeof *obj); if (!obj) { exit(EXIT_FAILURE); } obj-ob_base.ob_refcnt 1; obj-ob_base.ob_type PyInt_Type; obj-value value; return (PyObject *)obj; } static PyObject *PyFloat_FromDouble(double value) { PyFloatObject *obj malloc(sizeof *obj); if (!obj) { exit(EXIT_FAILURE); } obj-ob_base.ob_refcnt 1; obj-ob_base.ob_type PyFloat_Type; obj-value value; return (PyObject *)obj; } /* ---------------- Generic object printing ---------------- */ static void PyObject_Print(PyObject *obj) { if (!obj) { printf(NULL); return; } printf(%s, value, obj-ob_type-tp_name); obj-ob_type-tp_print(obj); printf(, refcnt%ld, obj-ob_refcnt); } /* This is the Python-like assignment operation. In Python: x some_object means: make x refer to some_object decrease reference to old object */ static void PyVar_Set(PyObject **label, PyObject *new_object) { if (!label) { return; } /* Protect new_object in case it is the same as *label. */ Py_Incref(new_object); /* Release old object. */ Py_Decref(*label); /* Rebind the label. */ *label new_object; } /* C11 _Generic allows a nicer macro: PY_SET(x, 5); PY_SET(x, 5.5); This is still not literally x 5, but it is close in spirit. */ #if defined(__STDC_VERSION__) __STDC_VERSION__ 201112L #define PY_SET(var, value) \ do { \ PyObject *tmp_ _Generic((value), \ int: PyInt_FromLong, \ long: PyInt_FromLong, \ float: PyFloat_FromDouble, \ double: PyFloat_FromDouble \ )(value); \ PyVar_Set((var), tmp_); \ Py_Decref(tmp_); \ } while (0) #endif int main(void) { /* x and y are not int variables or float variables. They are labels/references to Python-style objects. */ PyObject *x NULL; PyObject *y NULL; #ifdef PY_SET printf(x 5;\n); PY_SET(x, 5); printf(x - ); PyObject_Print(x); printf(\n\n); printf(x 5.5;\n); PY_SET(x, 5.5); printf(x - ); PyObject_Print(x); printf(\n\n); printf(y x;\n); PyVar_Set(y, x); printf(x - ); PyObject_Print(x); printf(\n); printf(y - ); PyObject_Print(y); printf(\n\n); printf(x 10;\n); PY_SET(x, 10); printf(x - ); PyObject_Print(x); printf(\n); printf(y - ); PyObject_Print(y); printf(\n\n); #else /* Fallback for non-C11 compilers */ PyObject *tmp; printf(x 5;\n); tmp PyInt_FromLong(5); PyVar_Set(x, tmp); Py_Decref(tmp); printf(x - ); PyObject_Print(x); printf(\n\n); printf(x 5.5;\n); tmp PyFloat_FromDouble(5.5); PyVar_Set(x, tmp); Py_Decref(tmp); printf(x - ); PyObject_Print(x); printf(\n\n); printf(y x;\n); PyVar_Set(y, x); printf(x - ); PyObject_Print(x); printf(\n); printf(y - ); PyObject_Print(y); printf(\n\n); printf(x 10;\n); tmp PyInt_FromLong(10); PyVar_Set(x, tmp); Py_Decref(tmp); printf(x - ); PyObject_Print(x); printf(\n); printf(y - ); PyObject_Print(y); printf(\n\n); #endif printf(cleanup:\n); Py_Decref(x); Py_Decref(y); return 0; }code2#include stdio.h #include stdlib.h /* Simplified Py_ssize_t */ typedef long Py_ssize_t; /* Forward declarations */ typedef struct PyObject PyObject; typedef struct PyTypeObject PyTypeObject; /* CPython-like base object. typedef struct _object { Py_ssize_t ob_refcnt; PyTypeObject *ob_type; } PyObject; */ struct PyTypeObject { const char *tp_name; void (*tp_print)(PyObject *self); void (*tp_dealloc)(PyObject *self); }; struct PyObject { Py_ssize_t ob_refcnt; /* reference count */ PyTypeObject *ob_type; /* dynamic type information */ }; /* Concrete object types. They start with PyObject so that PyObject* can be safely cast to them. */ typedef struct { PyObject ob_base; long value; } PyIntObject; typedef struct { PyObject ob_base; double value; } PyFloatObject; /* A mutable object type used to demonstrate shared mutable state. */ typedef struct { PyObject ob_base; long value; } PyBoxObject; /* ---------------- Printing functions ---------------- */ static void PyInt_Print(PyObject *self) { PyIntObject *obj (PyIntObject *)self; printf(%ld, obj-value); } static void PyFloat_Print(PyObject *self) { PyFloatObject *obj (PyFloatObject *)self; printf(%g, obj-value); } static void PyBox_Print(PyObject *self) { PyBoxObject *obj (PyBoxObject *)self; printf(box(%ld), obj-value); } /* ---------------- Deallocation functions ---------------- */ static void PyInt_Dealloc(PyObject *self) { PyIntObject *obj (PyIntObject *)self; printf([gc] dealloc int object %ld at %p\n, obj-value, (void *)obj); free(obj); } static void PyFloat_Dealloc(PyObject *self) { PyFloatObject *obj (PyFloatObject *)self; printf([gc] dealloc float object %g at %p\n, obj-value, (void *)obj); free(obj); } static void PyBox_Dealloc(PyObject *self) { PyBoxObject *obj (PyBoxObject *)self; printf([gc] dealloc box object %ld at %p\n, obj-value, (void *)obj); free(obj); } /* ---------------- Type objects ---------------- */ static PyTypeObject PyInt_Type { int, PyInt_Print, PyInt_Dealloc }; static PyTypeObject PyFloat_Type { float, PyFloat_Print, PyFloat_Dealloc }; static PyTypeObject PyBox_Type { box, PyBox_Print, PyBox_Dealloc }; /* ---------------- Reference counting ---------------- */ static void Py_Incref(PyObject *obj) { if (obj) { obj-ob_refcnt; } } static void Py_Decref(PyObject *obj) { if (!obj) { return; } obj-ob_refcnt--; if (obj-ob_refcnt 0) { obj-ob_type-tp_dealloc(obj); } } /* ---------------- Object constructors ---------------- */ static PyObject *PyInt_FromLong(long value) { PyIntObject *obj malloc(sizeof *obj); if (!obj) { exit(EXIT_FAILURE); } obj-ob_base.ob_refcnt 1; obj-ob_base.ob_type PyInt_Type; obj-value value; return (PyObject *)obj; } static PyObject *PyFloat_FromDouble(double value) { PyFloatObject *obj malloc(sizeof *obj); if (!obj) { exit(EXIT_FAILURE); } obj-ob_base.ob_refcnt 1; obj-ob_base.ob_type PyFloat_Type; obj-value value; return (PyObject *)obj; } static PyObject *PyBox_FromLong(long value) { PyBoxObject *obj malloc(sizeof *obj); if (!obj) { exit(EXIT_FAILURE); } obj-ob_base.ob_refcnt 1; obj-ob_base.ob_type PyBox_Type; obj-value value; return (PyObject *)obj; } /* ---------------- Object identity utilities ---------------- */ /* Similar to Python id(object). Here we simply use the objects memory address as its identity. */ static const void *PyObject_Id(PyObject *obj) { return (const void *)obj; } /* Similar to Python: a is b but here we use it mainly for non-NULL shared object checking. */ static int PyObject_IsShared(PyObject *a, PyObject *b) { return a ! NULL a b; } /* ---------------- Detailed validation printing ---------------- */ /* Print: - address of the label variable itself, e.g. x - address of the object it points to, e.g. x - object type - object value - reference count */ static void PyVar_PrintDetail(const char *label, PyObject **slot) { PyObject *obj slot ? *slot : NULL; printf(%-6s: label_addr%p, object_id%p, , label ? label : ?, (void *)slot, (void *)PyObject_Id(obj)); if (!obj) { printf(typeNULL, valueNULL, refcnt0\n); return; } printf(type%s, value, obj-ob_type-tp_name); obj-ob_type-tp_print(obj); printf(, refcnt%ld\n, obj-ob_refcnt); } /* Validate whether two labels refer to the same object. */ static void PyVar_ValidateShared(const char *label_a, PyObject **slot_a, const char *label_b, PyObject **slot_b) { PyObject *a slot_a ? *slot_a : NULL; PyObject *b slot_b ? *slot_b : NULL; printf(\n shared? %s(label_addr%p, object_id%p) vs %s(label_addr%p, object_id%p): , label_a ? label_a : ?, (void *)slot_a, (void *)PyObject_Id(a), label_b ? label_b : ?, (void *)slot_b, (void *)PyObject_Id(b)); if (!a !b) { printf(both NULL\n); return; } if (PyObject_IsShared(a, b)) { printf(YES, same object, refcnt%ld\n, a-ob_refcnt); } else { printf(NO, different objects\n); } } /* ---------------- Python-like assignment ---------------- */ /* In Python: x some_object means: make label x refer to some_object decrease reference to old object increase reference to new object */ static void PyVar_Set(PyObject **label, PyObject *new_object) { if (!label) { return; } /* Protect new_object in case it is the same as *label. */ Py_Incref(new_object); /* Release old object. */ Py_Decref(*label); /* Rebind the label. */ *label new_object; } /* ---------------- Mutable box operations ---------------- */ static void PyBox_Set(PyObject *self, long value) { if (!self || self-ob_type ! PyBox_Type) { fprintf(stderr, PyBox_Set: not a box object\n); return; } PyBoxObject *obj (PyBoxObject *)self; obj-value value; } static long PyBox_Get(PyObject *self) { if (!self || self-ob_type ! PyBox_Type) { fprintf(stderr, PyBox_Get: not a box object\n); return -1; } PyBoxObject *obj (PyBoxObject *)self; return obj-value; } /* ---------------- Demo ---------------- */ int main(void) { PyObject *x NULL; PyObject *y NULL; PyObject *tmp NULL; printf( Part 1: dynamic labels and shared object \n); printf(\n); printf(x 5\n); tmp PyInt_FromLong(5); PyVar_Set(x, tmp); Py_Decref(tmp); PyVar_PrintDetail(x, x); printf(x 5.5\n); tmp PyFloat_FromDouble(5.5); PyVar_Set(x, tmp); Py_Decref(tmp); PyVar_PrintDetail(x, x); printf(y x\n); PyVar_Set(y, x); PyVar_PrintDetail(x, x); PyVar_PrintDetail(y, y); PyVar_ValidateShared(x, x, y, y); printf(\n); printf(x 10\n); tmp PyInt_FromLong(10); PyVar_Set(x, tmp); Py_Decref(tmp); PyVar_PrintDetail(x, x); PyVar_PrintDetail(y, y); PyVar_ValidateShared(x, x, y, y); printf(\ncleanup part 1\n); Py_Decref(x); Py_Decref(y); x y NULL; printf(\n Part 2: mutable shared object \n); PyObject *a NULL; PyObject *b NULL; printf(\n); printf(a box(5)\n); tmp PyBox_FromLong(5); PyVar_Set(a, tmp); Py_Decref(tmp); PyVar_PrintDetail(a, a); printf(b a\n); PyVar_Set(b, a); PyVar_PrintDetail(a, a); PyVar_PrintDetail(b, b); PyVar_ValidateShared(a, a, b, b); printf(mutate through a: PyBox_Set(a, 99)\n); PyBox_Set(a, 99); printf(\n); PyVar_PrintDetail(a, a); PyVar_PrintDetail(b, b); printf(read through b: PyBox_Get(b) %ld\n, PyBox_Get(b)); PyVar_ValidateShared(a, a, b, b); printf(rebind a to a new object: a box(123)\n); tmp PyBox_FromLong(123); PyVar_Set(a, tmp); Py_Decref(tmp); printf(\n); PyVar_PrintDetail(a, a); PyVar_PrintDetail(b, b); PyVar_ValidateShared(a, a, b, b); printf(\ncleanup part 2\n); Py_Decref(a); Py_Decref(b); return 0; }

相关新闻

深信服SIP安全感知平台V3.0.53部署运维与告警处置指南

深信服SIP安全感知平台V3.0.53部署运维与告警处置指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 7:16:41 阅读更多 →
Java Web学生管理系统实战:Servlet+JSP+DBCP2从零搭建与排错指南

Java Web学生管理系统实战:Servlet+JSP+DBCP2从零搭建与排错指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/9/30 12:20:56 阅读更多 →
旁挂部署策略路由引流实战:从原理到排障的完整指南

旁挂部署策略路由引流实战:从原理到排障的完整指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 7:39:53 阅读更多 →

最新新闻

arXiv每日论文分析报告:自动抓取、语义打分与结构化摘要实战

arXiv每日论文分析报告:自动抓取、语义打分与结构化摘要实战

1. 一份“每日论文分析报告”到底在解决什么问题每天早上打开 arXiv 的 cs.CL、cs.LG、cs.CV 几个分区,新论文加起来动辄两三百篇,光是标题列表往下滚就要花掉十几分钟。更麻烦的是,标题和摘要之间存在巨大的信息差——有些标题看着平平无奇&…

2026/10/1 18:37:45 阅读更多 →
PX4 SensorAccelFifo 消息深度解析:加速度计 FIFO 批量数据通路与原始计数换算

PX4 SensorAccelFifo 消息深度解析:加速度计 FIFO 批量数据通路与原始计数换算

嵌入式物联网机器人自动驾驶智能硬件 【免费下载链接】PX4-Autopilot PX4 Autopilot Software 项目地址: https://gitcode.com/gh_mirrors/px/PX4-Autopilot 点击查看 免费下载 PX4 在常规的 sensor_accel(已标定加速度)消息之外&#xff0c…

2026/10/1 18:37:45 阅读更多 →
Debian系统深度解析:从包管理到网络与休眠控制的工程实践

Debian系统深度解析:从包管理到网络与休眠控制的工程实践

1. Debian是什么?它不是“另一个Linux”,而是一套精密运转的协作机制Debian是什么?这个问题看似简单,但如果你只回答“一个Linux发行版”,就像说“汽车就是四个轮子加个发动机”——技术上没错,但完全漏掉了…

2026/10/1 18:37:45 阅读更多 →
RAP 层次注解实战:从自引用表到 Fiori Elements Tree View

RAP 层次注解实战:从自引用表到 Fiori Elements Tree View

前阵子在做物料分类管理的 Fiori Elements 应用,数据量不大,一张 ytmclass 自引用表,无非就是 uuid 指向 parent_uuid 这种经典结构。第一版按普通 List Report 交付,岗位上的用户每天要看几千行分类,翻页翻得冒火&…

2026/10/1 18:37:45 阅读更多 →
Sass与Less对比:前端CSS预处理器选型与工程实践

Sass与Less对比:前端CSS预处理器选型与工程实践

写样式的时候要不要用预处理器?这个问题几乎每个前端都纠结过。我干了十多年前端,被问得最多的不是“怎么写CSS”,而是“Sass和Less到底选哪个”。网上教程一堆,但大多是抄官方文档,真正从项目实战角度把这事儿讲透的没…

2026/10/1 18:37:45 阅读更多 →
第一次编程作业实战:从读题到提交的完整流程

第一次编程作业实战:从读题到提交的完整流程

课程群里的通知弹出来时,我正对着教材第3章的目录发愁。标题只有一行字: 3.2第一次作业 。没有配图,没有额外解释,连提交方式都要自己点进附件里翻。头一回做这种需要交代码的作业,最折磨人的往往不是题目本身&#…

2026/10/1 18:36:44 阅读更多 →

日新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →

周新闻

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解

如何划分训练/验证集:Spirula Studio五种eval_mode策略详解 【免费下载链接】spirula-studio Cross-vendor 3D Gaussian Splatting trainer - video to splat to mesh, Vulkan or CUDA. 项目地址: https://gitcode.com/GitHub_Trending/sp/spirula-studio Sp…

2026/9/30 13:14:22 阅读更多 →
SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南

SEO怎么推广速查手册新手避坑实战指南 模板网站太丑不够用?别急着加滤镜,那是治标不治本。很多老板盯着后台流量掉得眼红,却还在纠结首页Banner的圆角是不是3像素。这就像穿着西装去挖土,姿势不对,努力白费。我整理这份 速查手册…

2026/9/30 18:13:06 阅读更多 →
FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏

FireRed-OpenStoryline少样本仿写深度解析:AI Agent如何复刻你的独特文案风格与节奏 【免费下载链接】FireRed-OpenStoryline FireRed-OpenStoryline is an AI video editing agent that transforms manual editing into intention-driven directing through natural language …

2026/9/30 13:14:49 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 0:00:30 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/1 1:01:17 阅读更多 →