Does RSTRING_PTR() return a '\0' terminated C?


#1

Hi, in a Ruby C extension I need to get a ‘\0’ terminated string given
a Ruby string. I’m just interesed in Ruby 1.9.

I’m testing that RSTRING_PTR(str) does returns a ‘\0’ terminated
string, ot it seems so, but I’m not sure. Source code says:

#define RSTRING_PTR(str)
(!(RBASIC(str)->flags & RSTRING_NOEMBED) ?
RSTRING(str)->as.ary :
RSTRING(str)->as.heap.ptr)

Honestly, no idea about what it does :slight_smile:

So, can somebody ensure me that RSTRING_PTR() returns a pointer to C
char finished with ‘\0’?

Thanks a lot.


#2

Iñaki Baz C. removed_email_address@domain.invalid wrote:

Honestly, no idea about what it does :slight_smile:

It’s one of my favorite things about Ruby 1.9: small strings (3 words -
1 byte) are embedded directly inside the object to avoid malloc()
overhead.

RSTRING_PTR() checks for the embed flag, and it’ll return the embedded C
string, otherwise it’ll return the pointer allocated from malloc().

The same thing is done with RArray and RStruct, looking at the structure
definitions will be useful.

So, can somebody ensure me that RSTRING_PTR() returns a pointer to C
char finished with ‘\0’?

It’s always ‘\0’-terminated in Ruby[1], it makes life much easier for
interacting with existing C functions that assume C strings (e.g.
*printf("%s"), open(), rename(), unlink(), etc…)

[1] - unless there’s a bug somewhere, or somebody hell bent on using the
extra byte :slight_smile:


#3

On Feb 4, 2011, at 12:07 PM, Eric W. wrote:

RSTRING(str)->as.heap.ptr)

The same thing is done with RArray and RStruct, looking at the structure
extra byte :slight_smile:
I don’t think this is true, use RSTRING_LEN with RSTRING_PTR to get the
length since the string may contain embedded NULLs.

If you want a safe C string use StringValueCStr().

PS: See also README.EXT section 1.3


#4

Hi,

In message “Re: Does RSTRING_PTR() return a ‘\0’ terminated C?”
on Sat, 5 Feb 2011 03:59:36 +0900, I$(D+P(Baki Baz C.
removed_email_address@domain.invalid writes:
|
|Hi, in a Ruby C extension I need to get a ‘\0’ terminated string given
|a Ruby string. I’m just interesed in Ruby 1.9.

It was true on 1.8 but no longer on 1.9. If you need NUL terminated
string, use StringValueCStr().

          matz.

#5

Eric H. removed_email_address@domain.invalid wrote:

On Feb 4, 2011, at 12:07 PM, Eric W. wrote:

It’s always ‘\0’-terminated in Ruby[1], it makes life much easier for
interacting with existing C functions that assume C strings (e.g.
*printf("%s"), open(), rename(), unlink(), etc…)

[1] - unless there’s a bug somewhere, or somebody hell bent on using the
extra byte :slight_smile:

I don’t think this is true, use RSTRING_LEN with RSTRING_PTR to get
the length since the string may contain embedded NULLs.

Yes, embedded NULLs are always a problem :confused:

If you want a safe C string use StringValueCStr().

Strange that StringValueCStr() NULL terminates explicitly, everywhere
else I look in string.c there’s always an extra byte allocated for NULL,
but I suppose one can’t be too careful in C.


#6

2011/2/5 Yukihiro M. removed_email_address@domain.invalid:

It was true on 1.8 but no longer on 1.9. If you need NUL terminated
string, use StringValueCStr().

Thanks to all. Indeed StringValueCStr() does the job. However until
now I was using:

c_str = RSTRING_PTR(rb_str);

and it always creates a ‘\0’ terminated C string (Ruby 1.9.2). However
I’m using very short strings (domain names), maybe this is the reason.

Thanks a lot.