Re: data exchange between two windows

Tech Tip: Click here to run a free scan for Windows Errors and optimize PC performance

From: Joseph M. Newcomer (newcomer_at_flounder.com)
Date: 05/24/04


Date: Mon, 24 May 2004 11:30:19 -0400

You are Not Getting It.

typedef struct {
             int x;
             int y;
            } whatever;

whatever * p = malloc(sizeof(whatever));

Assume you have many of these in the program. Now you change the struct to be

typedef struct {
            int x;
            int y;
            CString tag;
} whatever;

The CString will not be initialized, because its constructor is not called. So

        whatever * p = (whatever *)malloc(sizeof(whatever));
        p->tag = "Test";

will crash, because the CString constructor was not called to properly initialize the
CString data structure. So you will have to go around and change every malloc to new. So
why not do it right the first time? You would have created a program that is not robust
under maintenance, since it violates a key principle of C++ philosophy, and furthermore,
is based on some absurd idea such as "I like to do it this way" or "K&R used this in 1975,
in C, so it must be right in C++". You might as well decide that the only good programming
methodology was to put all the global variables in a single struct, and include a
definition of that struct not in a header file, but make a copy of it in every file that
uses it (we called this "unnamed COMMON" in FORTRAN, and people continued to use it after
"named COMMON" was introduced, because "they liked it" or "they understood it". When I
used named COMMON (I maintained, for several years, a large FORTRAN program that did wire
routing for wirewrap boards), I put exactly one variable per named common block, which had
the same name as the block. That is, I used it like "extern" in C or other languages.

There are good ways and bad ways to program. It is safe to assume that, with an
infinitesimal number of exceptions (for sophisticated objects which do unusual
allocation), that the use of malloc() in C++ is always a mistake. That's because it is a
mistake so much of the time that it makes no sense to consider it otherwise. Then, in
those extremely rare cases where it is appropriate (inside weird constructors, for
example), it becomes obvious that it is right. Note that I have never had to use it inside
a low-level constructor, either.

Try it.

It is clear you really don't understand constructors or their roles in C++. This failure
will occur in so many ways for so many different kinds of objects that there is never a
reason to argue in favor of using malloc to allocate user-defined objects. Had you
understood C++, you would not make such silly statements.

An inexperienced programmer who used new would see no problem. One who was so naive as to
use malloc would get a crash that was incomprehensible. An experienced programmer assumes
that the creator of the program is intelligent enough to use new all the time, and
therefore will see the same failure. This will require changing every site that does a
malloc.

Using malloc is irresponsible in C++ programs, except when used at the lowest level inside
constructors where raw storage must be dealt with. Note that this is an EXTREMELY rare
occurrence, since the default 'new' constructor handles low-level allocation already. So
promoting this to "good practice" or even "acceptable practice" is irresponsible. It
doesn't even come up to "remotely tolerable practice" on its best day.
                                                joe

On Mon, 24 May 2004 07:36:03 -0700, "Yasoo" <anonymous@discussions.microsoft.com> wrote:

>> pointer = new BYTE[100];
>
>The more I look at this syntax, the more I like it.
>
>
>What is the connection between using malloc, adding a CString, and seeing a bizarre failure? Here's what I see:
>
>I use malloc to define a block of memory. I have a pointer to the start of that area and I know how many bytes I asked for. When I want to use that memory, I use it. When I want a CString, I declare it and use it. I woulndn't even consider a CString pointer to part of that memory. Are you saying that using a CString might result in the CString using some of the malloc'ed memory?
>
>It seems to me, that if you have an inexperienced (clueless? :) ) programmer, you are gonna get bugs and bizarre failures anyway.
>
> - Kev
>
>Z++ Technologies

Joseph M. Newcomer [MVP]
email: newcomer@flounder.com
Web: http://www.flounder.com
MVP Tips: http://www.flounder.com/mvp_tips.htm



Relevant Pages

  • Re: TREE structure in MFC, how, where and why?
    ... Your struct contains a CString object, which is a C++ class with various ... By using malloc, the constructor on your CString is not being called. ...
    (microsoft.public.vc.mfc)
  • Re: TREE structure in MFC, how, where and why?
    ... I had not noticed the CString. ... >By using malloc, the constructor on your CString is not being called. ... >>terminal node and a tree node is that a terminal node has no children. ...
    (microsoft.public.vc.mfc)
  • Re: data exchange between two windows
    ... I would never use a CString as a member of a struct and use malloc in this combination (I might consider a pointer to a CString...)." ...
    (microsoft.public.vc.mfc)
  • Re: How to initialize a member struct
    ... I can't give this struct a constructor. ... class constructor (call it "TemplatedClass") in another DLL library. ... This leaves me with trying to come up with a way to initialize ...
    (microsoft.public.dotnet.languages.vc)
  • Re: Pointers, structs and memory allocations
    ... > lots of pointers and pointers to pointers which makes me confused. ... Hiding structs behind typedefs is only a good idea if the struct needs ... Casting malloc is a no no, ... for lists that are pretty short. ...
    (comp.lang.c)