Как выглядят паскальные строки в памяти?Как строки паскаля представлены в памяти?
Я читал: http://www.freepascal.org/docs-html/ref/refsu12.html В нем говорится, что строки хранятся в куче и подсчитываются ссылки. Для того, чтобы выяснить, где хранились длина и ссылок, я создал строку и сделал тесты на нем много:
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.
Первый печатает длину и второй один печатает количество ссылок. Он делает это отлично, и он работает.
Теперь я пытался подражать то же самое в 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;
}
Тогда в паскале я:
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.
Паскаля код печатает длину правильно и счетчик ссылок увеличивается на единицу из-за назначения. Это верно.
Однако, как только это будет завершено, он сильно сработает! Кажется, он пытается освободить строку/кучу. Если я сам вызываю FreeCString, он работает отлично! Я не уверен, что происходит.
Любые идеи, почему это происходит сбой?
Вы вводите в заблуждение несколько версий Pascal (Wirth/Turbo Pascal определили длину в байте 0, все после появления Delphi 2 длинными строками не будет, если они не объявлены как «ShortString»). Вы указали четыре разных языка в своих тегах. Вместо этого, почему бы вам не объяснить, что вы на самом деле пытаетесь сделать в первую очередь, и спросить, как это сделать? Почему это происходит из-за того, что вы делаете ошибочные предположения о вещах, которые неверны. –
Там. Я сузил языки. Я пытаюсь преобразовать строку c-style в строку pascal, не передавая также длину в качестве параметра. – Brandon
Что означает «Я пытаюсь преобразовать строку c-stype в строку pascal»? Delphi/Free Pascal может принимать строки с нулевым завершенным строком C отлично, без параметра длины; это делается тысячи раз в каждом приложении Windows (с помощью сделанных вызовов WinAPI). Еще раз, что вы на самом деле пытаетесь достичь? –