Are str* functions okay in C++?

Are str* functions okay in C++?

Post by Mark Jur » Sat, 09 Mar 1996 04:00:00



Hi all,
  I am relatively new to C++ and I'm having a heck of a time porting a C
program to C++.  I have a function that opens a man page and tries to
determine if it points to another man page.  I use strtok and strcpy in the
function.  It works fine under Solaris 2.x, however, under Linux 1.2.x or
1.3.x it chokes on a delete[] statement after several hundred iterations.
Here's the function.  It dies under Linux on the delete[] path; statement.

g++: 2.7.2
libg++: 2.7.1

on all platforms.  Is this a problem with my code, or is something else
going on here?

Notes:  mbuf[MAXLINE] is definately big enough
        *entry is definately big enough

// Check if the first line is an alias.  If so, get directory
void
Index::check_alias(char **entry,
                   char *f,
                   const char *dirname,
                   const char *fullpath)
{
  char mbuf[MAXLINE];
  char *alias, *ta, *path, *path2, *section, *tptr, *comm_name;;
  char *filename = new char[strlen(f)+1];
  static int num = 0;

  alias = ta = path = path2 = section = tptr = comm_name = 0;

  strcpy(filename,f);
  sprintf(mbuf,"%s/%s/%s",fullpath,dirname,f);

  ifstream infile(mbuf);
  if(!infile) error("Can't open manpage",mbuf);
  infile.getline(mbuf,MAXLINE);

  alias = new char[strlen(mbuf) + 1];
  strcpy(alias,mbuf);

  comm_name = strtok(filename,".");

  cout << "alias: " << alias << "\n";
  if((tptr = strstr(alias,".so")) != NULL){
    tptr += strlen(".so ");            // Gets, for instance, 'man2/utime.2'
    path = new char[strlen(fullpath) + strlen(tptr) + 2];

    sprintf(path,"%s/%s",fullpath,tptr);
    section = strtok(alias,"/");
    section = &section[strlen(section)-1];
  }
  else{
    sprintf(mbuf,"%s/%s/%s",fullpath,dirname,f);
    path = new char[strlen(mbuf)+1];

    strcpy(path,mbuf);
    section = (char *)&dirname[strlen(dirname)-1];
  }

  // Allocate for comm_name, section, path, 2 spaces and \0

  // Need to find an elegant way to check for existance before calling strlen
  path2 = new char[strlen(comm_name) + strlen(section) + strlen(path) + 3];

  sprintf(path2,"%s %s %s",comm_name,section,path);
  delete[] path;

  cout << "path2  " << path2 << " num " << num++ << "\n";
  strcpy(*entry,(char *)path2);

  delete[] path2;
  delete[] filename;

Quote:}

Thanks,

-Mark
__

 
 
 

Are str* functions okay in C++?

Post by dcm.. » Sat, 09 Mar 1996 04:00:00



Subject: Are str* functions okay in C++?
Date: 8 Mar 1996 18:50:40 GMT

Hi all,
  I am relatively new to C++ and I'm having a heck of a time porting a C
program to C++.  I have a function that opens a man page and tries to
determine if it points to another man page.  I use strtok and strcpy in
the
function.  It works fine under Solaris 2.x, however, under Linux 1.2.x
or
1.3.x it chokes on a delete[] statement after several hundred
iterations.
Here's the function.  It dies under Linux on the delete[] path;
statement.

g++: 2.7.2
libg++: 2.7.1

on all platforms.  Is this a problem with my code, or is something else
going on here?

Notes:  mbuf[MAXLINE] is definately big enough
        *entry is definately big enough

// Check if the first line is an alias.  If so, get directory
void
Index::check_alias(char **entry,
                   char *f,
                   const char *dirname,
                   const char *fullpath)
{
  char mbuf[MAXLINE];
  char *alias, *ta, *path, *path2, *section, *tptr, *comm_name;;
  char *filename = new char[strlen(f)+1];
  static int num = 0;

  alias = ta = path = path2 = section = tptr = comm_name = 0;

  strcpy(filename,f);
  sprintf(mbuf,"%s/%s/%s",fullpath,dirname,f);

  ifstream infile(mbuf);
  if(!infile) error("Can't open manpage",mbuf);
  infile.getline(mbuf,MAXLINE);

  alias = new char[strlen(mbuf) + 1];
  strcpy(alias,mbuf);

  comm_name = strtok(filename,".");

  cout << "alias: " << alias << "\n";
  if((tptr = strstr(alias,".so")) != NULL){
    tptr += strlen(".so ");            // Gets, for instance,
'man2/utime.2'
    path = new char[strlen(fullpath) + strlen(tptr) + 2];

    sprintf(path,"%s/%s",fullpath,tptr);
    section = strtok(alias,"/");
    section = &section[strlen(section)-1];
  }
  else{
    sprintf(mbuf,"%s/%s/%s",fullpath,dirname,f);
    path = new char[strlen(mbuf)+1];

    strcpy(path,mbuf);
    section = (char *)&dirname[strlen(dirname)-1];
  }

  // Allocate for comm_name, section, path, 2 spaces and \0

  // Need to find an elegant way to check for existance before calling
strlen
  path2 = new char[strlen(comm_name) + strlen(section) + strlen(path) +
3];

  sprintf(path2,"%s %s %s",comm_name,section,path);
  delete[] path;

  cout << "path2  " << path2 << " num " << num++ << "\n";
  strcpy(*entry,(char *)path2);

  delete[] path2;
  delete[] filename;

Quote:}

Thanks,

-Mark
__


 
 
 

Are str* functions okay in C++?

Post by Randy Charles Mor » Sun, 10 Mar 1996 04:00:00




Quote:>Hi all,
>  I am relatively new to C++ and I'm having a heck of a time porting a C
>program to C++.  I have a function that opens a man page and tries to
>determine if it points to another man page.  I use strtok and strcpy in the
>function.  It works fine under Solaris 2.x, however, under Linux 1.2.x or
>1.3.x it chokes on a delete[] statement after several hundred iterations.
>Here's the function.  It dies under Linux on the delete[] path; statement.

I'm thinking that maybe the delete[] isn't the problem, but that when you
allocated the path array, the allocation may have failed.  Only you can check
this.  I don't know the implementation and I don't have Linux running in my
office.

I suggestion is to give up on old C functions that do string manipulation and
begin using a string class.  In the MFC library, the class CString is
great.  And in the OWL library, the class String is even better.  I don't know
what's available for Unix or if these classes are appropriate for your
framework.  Maybe somebody else will suggest or send you a string class.  HEY
EVERYBODY, SEND THIS GUY A WORKING LINUX CLASS.  Think they heard me?

Agrivar

 
 
 

Are str* functions okay in C++?

Post by Ralf W. Steph » Sun, 10 Mar 1996 04:00:00


I'd suspect some pointer snafu/overwrite in your code that silently
passes on the other machine but doesn't go unrecognized under Linux.
I'd suggest using a debugging library like libefence, or better,
libdmalloc.  Even better (and more to the spirit of C++) would be
if you used string instead of char*.

Good luck,
ralf
--
PGP: 1024/0xA713ECE9 2047/0xC8E605F5

 
 
 

Are str* functions okay in C++?

Post by Randy Chapm » Wed, 13 Mar 1996 04:00:00




: >    path = new char[strlen(mbuf)+1];
: >    strcpy(path,mbuf);

: One quick note: there's a "strdup()" function which handles this
: for you, although it uses "free" instead of "delete."

: Also, another useful technique for this type of code is:

: void procedure (argument...)
:    {
:    static char * buffer = 0;

:    if (buffer == 0)
:        buffer = malloc (2048);  /* or any _large_ number */

:    ...
:    sprintf (buffer, format,...)
:    path = strdup (buffer);
:    ...

: The idea is that "buffer" is a captive memory leak -- you allocate a
: large buffer once and never release it.  That increases the runtime
: size of your program, but eliminates the performance hit and possible
: memory leaks from repeatedly allocating and deleting small blocks.

However, it limits you to non-multithreaded programs.  Its little things
like this that make trying to use existing code in a multithreaded
environment really hard sometimes =(

--randy

 
 
 

Are str* functions okay in C++?

Post by Bear Gil » Wed, 13 Mar 1996 04:00:00




>    path = new char[strlen(mbuf)+1];
>    strcpy(path,mbuf);

One quick note: there's a "strdup()" function which handles this
for you, although it uses "free" instead of "delete."

Also, another useful technique for this type of code is:

void procedure (argument...)
   {
   static char * buffer = 0;

   if (buffer == 0)
       buffer = malloc (2048);  /* or any _large_ number */

   ...
   sprintf (buffer, format,...)
   path = strdup (buffer);
   ...

The idea is that "buffer" is a captive memory leak -- you allocate a
large buffer once and never release it.  That increases the runtime
size of your program, but eliminates the performance hit and possible
memory leaks from repeatedly allocating and deleting small blocks.

 
 
 

Are str* functions okay in C++?

Post by Henrik Nordstr » Fri, 15 Mar 1996 04:00:00


: The idea is that "buffer" is a captive memory leak -- you allocate a
: large buffer once and never release it.  That increases the runtime
: size of your program, but eliminates the performance hit and possible
: memory leaks from repeatedly allocating and deleting small blocks.

I prefer to use local variables instead (and of course running in
an environment where the stack space is enought). In most systems
this has no or very low performance degration, supports multithreading,
no memory leaks,...

---
Henrik Nordstrom
University of Skoevde
Sweden

 
 
 

Are str* functions okay in C++?

Post by Noel Feg » Sat, 16 Mar 1996 04:00:00



>   <snip>
>void procedure (argument...)
>   {
>   static char * buffer = 0;
>   if (buffer == 0)
>       buffer = malloc (2048);  /* or any _large_ number */
>   ...
>   sprintf (buffer, format,...)
>   path = strdup (buffer);
>   ...
>   <snip>

In my experience The use of malloc and free in a C++ application should be
avoided. From what I've read this is generally what is advised. This would also
mean that functions like strdup should be avoided also, because, as you
mentioned, you have to use free on the memory block returned by strdup, not
delete. I'm sure you are very careful with this but others maintaining you code
may not realise the implications.

I'm not saying that they do not work but it introduce the potential problem
where free is using on a "new"ed memory block, etc.

Apart from this, I do not follow your reason for using a "captive memory leak".
This memory block is not deleted at any stage during the program, and as such is
a memory leak as you mentioned. You rely on the good nature of the operating
system to clean up all the memory taken by the program when it has finished
executing, even if the program does not delete it itself. I'm think this is a
bit risky. If you main concern is fragementation of memory or stack size why not
have the following:

void procedure (argument...)
  {
  static char buffer[2048];

  ...
  sprintf(buffer, format,...);
  path = new char[strlen(buffer)+1];
  strcpy(path, buffer);
  ...

This would be a static buffer which is allocated by the program when it is
initializing and free when the program terminates, there is no memory leak and
the memory does not get fragmented.

I would recommend using a string class instead of having to add lines like "path
= new ..." and the "strcpy(..." every time you want to copy a string. Or you
could write a function which did the equivalent of strdup but used new instead
of malloc.
--
Noel Fegan
European Software Development Department
American Power Conversion
I don't speak for APC...

 
 
 

Are str* functions okay in C++?

Post by Keith Freem » Thu, 21 Mar 1996 04:00:00





> > : Also, another useful technique for this type of code is:

> > : void procedure (argument...)
> > :    {
> > :    static char * buffer = 0;

> > :    if (buffer == 0)
> > :        buffer = malloc (2048);  /* or any _large_ number */
> > :    ...
> > However, it limits you to non-multithreaded programs.  Its little things
> > like this that make trying to use existing code in a multithreaded
> > environment really hard sometimes =(

And, this can cause very subtle problems in single-threaded programs.
If your function returns a pointer to the buffer (like the standard
library function strtok()), many users will naively:

  1) call it several times, storing each returned (identical!)
     pointer somewhere;

  2) place more than one call in the argument list passed to another
     function (all point to the same result, but which one?)

keith freeman

 
 
 

1. Okay, Okay, Okay--NT and Linux

A while back I posted this question and the best response I got from a nice
gentleman in Europe, was a FAQ in German.  The problem is that I don't
spracken Deutsch!  So here it goes again:

Can anyone offer any solutions to having a Linux box dial into NT RAS for
network connectivity?

Any answers in English, Spanish, Pig Latin, and maybe even French ( after
drinking a few Coronas) would be great!

Thanks,
Nate El Great

2. align

3. Is there a strtof() function (str to float)?

4. SB16 MPU-401 midi

5. okay I am NEWBIE and i need some help: RPM failures????

6. tty1 behaving strangely

7. C++ class member function as a thread function.

8. busy inodes

9. why distinguish C++ function from C function?

10. How does c function invoke c++ function in shared object on RHL 6.2?

11. C functions calling C++ functions on Solaris

12. Plug-Ins using C++

13. Autoprobe hangs during installation - - Machine known to function okay in W95.