[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[50 character or so descriptive subject here (for reference)]
From: |
John W. Eaton |
Subject: |
[50 character or so descriptive subject here (for reference)] |
Date: |
Thu, 8 Nov 2001 23:58:35 -0600 |
On 18-Oct-2001, Douglas Eck <address@hidden> wrote:
| To: address@hidden
| Cc: doug
| Subject: [50 character or so descriptive subject here (for reference)]
|
| Bug report for Octave 2.0.16.92 configured for i386-pc-linux-gnu
|
| Description:
| -----------
|
| Using const char * c = args(0).string_value().c_str();
| to get a string from the argument vector sometimes results
| in unpredictable results.
|
| Repeat-By:
| ---------
|
| /*
| This code snippet shows that using c_str() has
| unpredictable results when parsing args in an .oct file.
|
| This might not be an octave bug (in fact, it probably isn't)
| but it took me a while to find so I wanted to submit it.
|
| I am running the latest debian unstable.
|
| Here is a test run of this code on my system:
|
| 432 ruchetta ~/beat/dynamic>mkoctfile -v bad_cstr.cc
| c++ -c -fPIC -I/usr/include/octave-2.1.34 -I/usr/include/octave-2.1.34/octave
-I/usr/include -mieee-fp -fno-implicit-templates -O2 bad_cstr.cc -o bad_cstr.o
| c++ -shared -o bad_cstr.oct bad_cstr.o
| 433 ruchetta ~/beat/dynamic>octave
| GNU Octave, version 2.1.34 (i386-pc-linux-gnu).
| Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001 John W. Eaton.
| This is free software with ABSOLUTELY NO WARRANTY.
| For details, type `warranty'.
|
| *** This is a development version of Octave. Development releases
| *** are provided for people who want to help test, debug, and improve
| *** Octave.
| ***
| *** If you want a stable, well-tested version of Octave, you should be
| *** using one of the stable releases (when this development release
| *** was made, the latest stable version was 2.0.16).
|
| PS1 = Octave >>
| PS2 =
| beep_on_error = 0
| default_save_format = mat-binary
| define_all_return_values = 0
| do_fortran_indexing = 0
| empty_list_elements_ok = 1
| fixed_point_format = 1
| implicit_num_to_str_ok = 1
| implicit_str_to_num_ok = 1
| ok_to_lose_imaginary_part = 1
| page_screen_output = 0
| prefer_column_vectors = 0
| prefer_zero_one_indexing = 1
| print_empty_dimensions = 0
| treat_neg_dim_as_zero = 1
| warn_function_name_clash = 0
| whitespace_in_literal_matrix = traditional
| Octave >>
bad_cstr("12345678901234567890123456789012345678901234567890123456789012345678901234567890")
| Test 1 with broken c_str()
| Incoming char * c is 7890123456789012345678901234567890123456789012345678
| New char * n1 is
12345678901234567890123456789012345678901234567890123456789012345678
|
| Test 2 with explicit copy from the string
| Old string s is
12345678901234567890123456789012345678901234567890123456789012345678901234567890
| New char * n2 is
12345678901234567890123456789012345678901234567890123456789012345678901234567890
| Octave >>
| */
|
| #include <octave/oct.h>
|
|
| DEFUN_DLD (bad_cstr, args, ,
| "call like this: cpystr(string x) where x is a long string as in
this example:
|
bad_cstr(\"12345678901234567890123456789012345678901234567890123456789012345678901234567890\")
| ")
| {
| octave_value_list retval;
| const char * c = args(0).string_value().c_str();
| int sz=strlen(c);
| char * n1 = new char[sz];
| strcpy(n1,c);
| cout << "Test 1 with broken c_str() " << endl;
| cout << "Incoming char * c is " << c << endl;
| cout << " New char * n1 is " << n1 << endl;
|
| cout << endl << "Test 2 with explicit copy from the string " << endl;
| string s = args(0).string_value();
| char * n2 = new char[sz];
| for (int i=0;i<sz;i++)
| n2[i]=s[i];
| cout << " Old string s is " << s << endl;
| cout << "New char * n2 is " << n2 << endl;
|
| return retval;
| }
|
|
| Fix:
| ---
|
| I worked around it by doing explicit copies from the
| std::string rather than the char * from c_str().
| Perhaps (probably?) this is a bug in my debian distro,
| not in octave.
I don't think it is a bug in Octave. I see a couple of problems with
your code. First, you haven't left room for the terminating NUL
character in the C strings, and when you copied it (this is a good
argument against C strings and in favor of C++ string objects, IMHO).
Also, there seems to be a problem with the lifetime of temporaries.
If you write
string s = args(0).string_value();
const char *c = s.c_str();
instead of just
const char *c = args(0).string_value().c_str();
then it seems to work correctly. Here's my modified fucntion that
seems to work:
#include <octave/oct.h>
DEFUN_DLD (bad_cstr, args, ,
"call like this: cpystr(string x) where x is a long string as in
this example:
bad_cstr(\"12345678901234567890123456789012345678901234567890123456789012345678901234567890\")
")
{
octave_value_list retval;
string s = args(0).string_value();
const char * c = s.c_str();
int sz=strlen(c);
char * n1 = new char[sz] + 1;
strcpy(n1,c);
cout << "Test 1 with broken c_str() " << endl;
cout << "Incoming char * c is " << c << endl;
cout << " New char * n1 is " << n1 << endl;
cout << endl << "Test 2 with explicit copy from the string " << endl;
char * n2 = new char[sz] + 1;
for (int i=0;i<sz;i++)
n2[i]=s[i];
n2[sz] = '\0';
cout << " Old string s is " << s << endl;
cout << "New char * n2 is " << n2 << endl;
return retval;
}
jwe
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [50 character or so descriptive subject here (for reference)],
John W. Eaton <=