如何帕斯卡尔字符串重新在内存psented $ P $? [英] How are pascal strings represented in memory?

查看:76
本文介绍了如何帕斯卡尔字符串重新在内存psented $ P $?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

如何帕斯卡尔字符串在内存布局?

How are pascal strings laid out in memory?

我读: http://www.freepascal.org/docs-html /ref/refsu12.html
它说,字符串存储在堆和引用计数。为了弄清楚储存长度和参考的地方,我创建了一个字符串,并在其上​​做试验了很多:

I read: http://www.freepascal.org/docs-html/ref/refsu12.html It says that strings are stored on the heap and reference counted. To figure out where the length and reference was stored, I created a string and did tests on it a lot:

type PInt = ^Integer;

var
    str: String;
begin
    str := 'hello';
    writeln(PInt(@str[1]) - (sizeof(integer) * 1)); //length
    writeln(PInt(@str[1]) - (sizeof(integer) * 2)); //reference count
end.

第一个打印的长度,第二个打印的引用计数。它这样做是完全没有问题和它的作品。

The first one prints the length and the second one prints the reference count. It does this perfectly fine and it works.

现在我试图效仿在C同样的事情:

Now I tried to emulate the same thing in C:

Export char* NewCString()
{
    const char* hello_ptr = "hello";

    int length = strlen(hello_ptr);

    //allocate space on the heap for:  sizeof(refcount) + sizeof(int) + strlength
    char* pascal_string = (char*)malloc((sizeof(int) * 2) + length);

    *((int*)&pascal_string[0]) = 0; //reference count to 0.
    *((int*)&pascal_string[sizeof(int)]) = length;  //length of the string.

    strcpy(&pascal_string[sizeof(int) * 2], hello_ptr); //copy hello to the pascal string.

    return &pascal_string[sizeof(int) * 2]; //return a pointer to the data.
}

Export void FreeCString(char* &ptr)
{
    int data_offset = sizeof(int) * 2;
    free(ptr - data_offset);
    ptr = NULL;
}

然后在帕斯卡我做的:

Then in pascal I do:

var
    str: string;
begin
    str := string(NewCString());
    writeln(PInt(@str[1]) - (sizeof(integer) * 1)); //length - prints 5. correct.
    writeln(PInt(@str[1]) - (sizeof(integer) * 2)); //reference count - prints 1! correct.
   //FreeCString(str);  //works fine if I call this..
end.

帕斯卡code打印正确的长度和引用计数增加一个因分配。这是正确的。

The pascal code prints the length correctly and the reference count is increased by one due to the assignment. This is correct.

不过,一旦它执行完毕后,崩溃厉害!这似乎是试图释放字符串/堆。如果我叫FreeCString自己,它工作得很好!我不知道是怎么回事。

However, as soon as it is finished executing, it crashes badly! It seems to be trying to free the string/heap. If I call FreeCString myself, it works just fine! I'm not sure what is going on.

任何想法,为什么它崩溃?

Any ideas why it crashes?

推荐答案

仅仅因为运行时系统勾画出字符串一种特殊的方式在内存中,并不意味着编写C code复制内存布局工作。字符串管理可能涉及额外的约束或外部数据结构。为了使字符​​串FreePascal的兼容,使用FreePascal的自己的库函数。

Just because the runtime system lays out strings a particular way in memory, doesn't mean that writing C code to duplicate that memory layout will work. String management may involve additional constraints or external data structures. To make a string compatible with FreePascal, use FreePascal's own library routines.

这听起来像FreePascal的要求,除了的东西免费()时,引用计数变成零,但它可能无法知道什么没有一些逆向工程或挖掘到ABI规格发生

It sounds like FreePascal requires something besides free() happen when the refcount goes to zero, but it's likely impossible to tell what without some reverse engineering or digging into ABI specs.

这篇关于如何帕斯卡尔字符串重新在内存psented $ P $?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆