In article <43151ba30909270827j6aacad8fu16401e6936a392db / mail.gmail.com>,
  "Masahiro Kanai (CanI)" <cani.m.61st / gmail.com> writes:

> ・ruby上で、元のStructに破壊的変更を加えることは可能でしょうか?

とりあえず、rb_check_string_type あたりが狙い目じゃないでしょ
うか。

> @@ -7048,13 +7053,15 @@ static VALUE
>  rb_str_start_with(int argc, VALUE *argv, VALUE str)
>  {
>      int i;
> +    char *ptr = RSTRING_PTR(str);
> +    long len = RSTRING_LEN(str);
>
>      for (i=0; i<argc; i++) {
>  	VALUE tmp = rb_check_string_type(argv[i]);
>  	if (NIL_P(tmp)) continue;
>  	rb_enc_check(str, tmp);
> -	if (RSTRING_LEN(str) < RSTRING_LEN(tmp)) continue;
> -	if (memcmp(RSTRING_PTR(str), RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
> +	if (len < RSTRING_LEN(tmp)) continue;
> +	if (memcmp(ptr, RSTRING_PTR(tmp), RSTRING_LEN(tmp)) == 0)
>  	    return Qtrue;
>      }
>      return Qfalse;

% cat z.rb                
$a = "a"*1000
b = Object.new
def b.to_str
  $a.replace "b"*1000
  "a"
end
p $a.start_with?(b)

% valgrind ./miniruby z.rb
==26867== Memcheck, a memory error detector.
==26867== Copyright (C) 2002-2007, and GNU GPL'd, by Julian Seward et al.
==26867== Using LibVEX rev 1854, a library for dynamic binary translation.
==26867== Copyright (C) 2004-2007, and GNU GPL'd, by OpenWorks LLP.
==26867== Using valgrind-3.3.1-Debian, a dynamic binary instrumentation framework.
==26867== Copyright (C) 2000-2007, and GNU GPL'd, by Julian Seward et al.
==26867== For more details, rerun with: -v
==26867== 
==26867== Invalid read of size 1
==26867==    at 0x4025087: bcmp (mc_replace_strmem.c:442)
==26867==    by 0x814286D: rb_str_start_with (string.c:6847)
==26867==    by 0x817FB06: call_cfunc (vm_insnhelper.c:286)
==26867==    by 0x817F9B5: vm_call_cfunc (vm_insnhelper.c:386)
==26867==    by 0x817EFD9: vm_call_method (vm_insnhelper.c:511)
==26867==    by 0x817ACAD: vm_exec_core (insns.def:994)
==26867==    by 0x818735C: vm_exec (vm.c:1117)
==26867==    by 0x81879CF: rb_iseq_eval_main (vm.c:1341)
==26867==    by 0x808B920: ruby_exec_node (eval.c:212)
==26867==    by 0x808B9C1: ruby_run_node (eval.c:240)
==26867==    by 0x805D1F7: main (main.c:35)
==26867==  Address 0x439e278 is 0 bytes inside a block of size 1,001 free'd
==26867==    at 0x4022B8A: free (vg_replace_malloc.c:323)
==26867==    by 0x8099CBC: vm_xfree (gc.c:730)
==26867==    by 0x8099E13: ruby_xfree (gc.c:778)
==26867==    by 0x8131510: str_discard (string.c:1279)
==26867==    by 0x8139F71: rb_str_replace (string.c:3733)
==26867==    by 0x817FB3B: call_cfunc (vm_insnhelper.c:292)
==26867==    by 0x817F9B5: vm_call_cfunc (vm_insnhelper.c:386)
==26867==    by 0x817EFD9: vm_call_method (vm_insnhelper.c:511)
==26867==    by 0x817ACAD: vm_exec_core (insns.def:994)
==26867==    by 0x818735C: vm_exec (vm.c:1117)
==26867==    by 0x8182633: vm_call0 (vm_eval.c:64)
==26867==    by 0x8183312: rb_call0 (vm_eval.c:283)
true
==26867== 
==26867== ERROR SUMMARY: 1 errors from 1 contexts (suppressed: 25 from 1)
==26867== malloc/free: in use at exit: 377,787 bytes in 12,896 blocks.
==26867== malloc/free: 13,198 allocs, 302 frees, 1,171,105 bytes allocated.
==26867== For counts of detected errors, rerun with: -v
==26867== searching for pointers to 12,896 not-freed blocks.
==26867== checked 420,024 bytes.
==26867== 
==26867== LEAK SUMMARY:
==26867==    definitely lost: 253,258 bytes in 8,953 blocks.
==26867==      possibly lost: 0 bytes in 0 blocks.
==26867==    still reachable: 124,529 bytes in 3,943 blocks.
==26867==         suppressed: 0 bytes in 0 blocks.
==26867== Rerun with --leak-check=full to see details of leaked memory.
-- 
[田中 哲][たなか あきら][Tanaka Akira]