- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我正在尝试从内存中删除密码字符串 like it is suggested in here .
我写了那个小片段:
import ctypes, sys
def zerome(string):
location = id(string) + 20
size = sys.getsizeof(string) - 20
#memset = ctypes.cdll.msvcrt.memset
# For Linux, use the following. Change the 6 to whatever it is on your computer.
print ctypes.string_at(location, size)
memset = ctypes.CDLL("libc.so.6").memset
memset(location, 0, size)
print "Clearing 0x%08x size %i bytes" % (location, size)
print ctypes.string_at(location, size)
a = "asdasd"
zerome(a)
奇怪的是,这段代码在 IPython 上运行良好,
[7] oz123@yenitiny:~ $ ipython a.py
Clearing 0x02275b84 size 23 bytes
但是使用 Python 会崩溃:
[8] oz123@yenitiny:~ $ python a.py
Segmentation fault
[9] oz123@yenitiny:~ $
有什么想法吗?
我使用 Python 2.7.3 在 Debian Wheezy 上进行了测试。
该代码适用于 CentOS 6.2 和 Python 2.6.6。 代码在使用 Python 2.6.8 的 Debian 上崩溃。 我试着思考为什么它适用于 CentOS 而不是 Debian。唯一的原因, 立即不同的是,我的 Debian 是多架构的,而 CentOS 在我的 i686 CPU 旧笔记本电脑上运行。
因此,我重新启动了我的 CentOS latop 并在其上加载了 Debian Wheezy。 该代码适用于非多体系结构的 Debian Wheezy。 因此,我怀疑我在 Debian 上的配置有点问题......
最佳答案
ctypes 已经有一个 memset
函数,所以你不必为 libc/msvcrt 函数创建一个函数指针。此外,20 个字节用于常见的 32 位平台。在 64 位系统上,它可能是 36 个字节。这是 PyStringObject
的布局:
typedef struct {
Py_ssize_t ob_refcnt; // 4|8 bytes
struct _typeobject *ob_type; // 4|8 bytes
Py_ssize_t ob_size; // 4|8 bytes
long ob_shash; // 4|8 bytes (4 on 64-bit Windows)
int ob_sstate; // 4 bytes
char ob_sval[1];
} PyStringObject;
因此在 32 位系统上可能是 5*4 = 20 字节,在 64 位 Linux 上可能是 8*4 + 4 = 36 字节,在 64 位 Windows 上可能是 8*3 + 4*2 = 32 字节.由于字符串未使用垃圾收集 header 进行跟踪,因此您可以使用 sys.getsizeof
。一般来说,如果您不想包含 GC header 大小(在内存中它实际上位于您从 id
获取的对象基地址之前),则使用对象的 __sizeof__
方法。至少这是我的经验中的一般规则。
您想要的只是从对象大小中减去缓冲区大小。 CPython 中的字符串以 null 结尾,因此只需将其长度加 1 即可获得缓冲区大小。例如:
>>> a = 'abcdef'
>>> bufsize = len(a) + 1
>>> offset = sys.getsizeof(a) - bufsize
>>> ctypes.memset(id(a) + offset, 0, bufsize)
3074822964L
>>> a
'\x00\x00\x00\x00\x00\x00'
编辑
更好的选择是定义 PyStringObject
结构。这使得检查 ob_sstate
变得很方便。如果它大于 0,则意味着该字符串已被驻留,理智的做法是引发异常。单字符字符串与仅由 ASCII 字母和下划线组成的代码对象中的字符串常量以及解释器在内部用于名称(变量名称、属性)的字符串一起被驻留。
from ctypes import *
class PyStringObject(Structure):
_fields_ = [
('ob_refcnt', c_ssize_t),
('ob_type', py_object),
('ob_size', c_ssize_t),
('ob_shash', c_long),
('ob_sstate', c_int),
# ob_sval varies in size
# zero with memset is simpler
]
def zerostr(s):
"""zero a non-interned string"""
if not isinstance(s, str):
raise TypeError(
"expected str object, not %s" % type(s).__name__)
s_obj = PyStringObject.from_address(id(s))
if s_obj.ob_sstate > 0:
raise RuntimeError("cannot zero interned string")
s_obj.ob_shash = -1 # not hashed yet
offset = sizeof(PyStringObject)
memset(id(s) + offset, 0, len(s))
例如:
>>> s = 'abcd' # interned by code object
>>> zerostr(s)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<string>", line 10, in zerostr
RuntimeError: cannot zero interned string
>>> s = raw_input() # not interned
abcd
>>> zerostr(s)
>>> s
'\x00\x00\x00\x00'
关于python - python 中的 ctypes 因 memset 而崩溃,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15581881/
在互联网上浏览代码时,我经常看到这样的片段: struct epoll_event event; memset(&event, 0, sizeof(event)); 如果事件填写完整,这种模式对我来说
我不认为我在这里理解了什么...... bool (*lookup)[100]; memset(lookup, 0, 100 * sizeof(*lookup)); 我正在尝试初始化一个指向堆栈分配数
我从以前退休的开发人员那里继承了一些代码。我的问题具体是在以下场景中使用 memset。不是 c 程序员,我想知道为什么在这种特殊情况下使用 memset,其中下一行代码将值存储在刚刚被 memset
如何在 jsctypes 中使用 memset。没有对应的 DLL。我搜索/搜索了 js ctype 代码,但找不到要破解的示例。 最佳答案 如果您只想将数组memset为零字节,那么我有“好消息,大
在尝试重新创建“memset”函数时,如果我尝试取消引用 void 指针,或者第二个参数的类型与第一个参数的类型不同,则会出现错误。为了使该功能正常工作,我必须将其更改为: void ft_memse
我关注了How to memset char array with null terminating character?在使用 C memset api 时添加空终止符。 代码有效;由于空终止符,我
这个问题在这里已经有了答案: Calloc with structure with pointers in C (3 个答案) 关闭 7 年前。 考虑以下对 void 指针数组的初始化: #incl
我写了这段代码: #include int main(void) { char c[10]=""; //Q if(c[2]=='\0')
我正在尝试为 2D 矩阵分配内存,但出现段错误。 int** inicializarMatriz(int **matriz, int vertices){ int i; matriz=(int**)
已关闭。此问题需要 debugging details 。目前不接受答案。 编辑问题以包含 desired behavior, a specific problem or error, and the
这给我带来了 memset 的段错误,我不知道为什么,我要访问 2D 数组的特定索引,这应该给我一个 char 指针并允许我使用 memeset。 void test(char** test) {
我正在尝试增长一个数组以添加新的 malloc 指针。 realloc 似乎并没有增加大小。另外,我一开始就为数组中的一个指针提供了足够的空间,因此即使 realloc 没有增加大小,我仍然希望能够复
我正在用 C 语言做一个关于 UDP 套接字的练习。当客户端发送特定消息(例如 hi)时,服务器必须发送“很高兴见到你”。如果没有找到标准回复,服务器将发送“没有合适的回复”。我的问题是memset如
由于memset采用字符串或数组的地址并将它们视为字符缓冲区。 它如何知道必须分配的给定值应该以 1 字节(字符)为一组还是以 4 字节为一组进行分配(整数)。 最佳答案 但事实并非如此。在第三个参数
我想避免使用memset()在这样的结构上: typedef struct { int size; float param1; } StructA; typedef struct {
我有以下一组代码,无法找到为什么我得到垃圾值。我的目的是将字节数复制为目标,而不考虑源,以便为我的应用程序制作通用副本。但没有得到正确的结果。有什么办法可以实现这一点。 int main() {
我定义了一个结构体,以及一个接受结构体指针并填充相关信息的函数,同时在开始时进行空检查。 粗略示例: typedef struct { int field; } myStruct; void my
我在编写一个函数来从文件中提取字符串作为更大程序的一部分时遇到一些问题。一切似乎都工作正常,除了当我使用 memset 或 bzero 来删除我一直在使用的字符数组时。我已经解决这个问题一个多小时了,
void readdat (int c, char **v) { char *dc; char *pdc; dc = malloc((line+1) * sizeof(char)); memset(d
我有一个指向数组的指针。我知道该数组可以容纳多少个项目,但每个项目的长度是动态的。那么在这种情况下如何memset()数组。 Int8 *data[4]; //array can hold maxim
我是一名优秀的程序员,十分优秀!