An error message in GDI + programming and analysis

xiaoxiao2021-03-06  18

The company does not let the piracy, prepare each software either replace it into open source, or write, look at it, it is the simplest number of ACDSEE (some advanced features are all used), line, start from this.

Demand Analysis: Basic image viewing features, image format conversion feature, basic graphical transformation function.

Technical feasibility analysis: GDI provided by MS

It has provided a professional graphic display, format conversion function, and is easy to use.

....

OK, ready, start dry.

However, in the process of programming, there is an error message makes me very unconfil. There is a statement in the program:

BMPHOTO

=

New bitmap

(Thumbnail_width

Thumbnail_height

Pixelformat24bpprgb

);

Each time debug is compiled, the following error is reported:

Error C2660

:

'new'

: Function Does

NOT TAKE

3 parameters

Start thinking is a problem with the building function of Bitmap, but check it, Bitmap is clearly constructed:

Bitmap

(In int width

,

In int Height

,

In Pixelformat Format

= Pixelformat32bppargb

);

What is the problem? The Internet discussed, and finally lock the problem in such a macro in the MFC program:

#ifdef _debug # define new debug_new # undef this_file

Static

Char this_file

[] = __File__

;

#ENDIF These lines never caused what problems with the code we pay attention to?

• Why make our code report to compile errors as described above?

?

Let's take a look at Debug_New definition (in AFX)

in .h):

#if defined (_Debug) &&! defined (_AFX_NO_DEBUG_CRT)

// Memory TRACKING ALLOCATION

Void

* AFX_CDECL

Operator new

(SIZE_T NSIZE

, LPCSTR LPSZFILENAME

,

Int nline

);

#define debug_new new (this_file, __line __) # if _msc_ver> = 1200

Void AFX_CDECL

Operator delete

(

Void

* P

, LPCSTR LPSZFILENAME

,

Int nline

);

#ENDIF See here you might think,

New was become Debug_new by Define, and the latter was become Define.

New

(...), this is not a cycle

? Due to AFX

.H earlier than any other header file is included

(stdafx

.h contains AFXWIN

Hh, AFXWIN

.h contains AFX

.h, and MFC requires us to include STDAFX before any valid code

.h, of course, this is not necessary

), So Debug_new defines the next #define behind it.

New debug_new, that is, this Define is only valid for the rear code, and the AFX that has been included in front.

The code in .h is invalid.

Only the topic is now, now returns to the topic.

MFC overload

Operator new, is to facilitate positioning memory leaks, after heavy load

The Operator New will record __file__ and __line__ information corresponding to each block allocated. Generally speaking, the standard Operator New declaration is as follows:

Void

* __ cdecl

Operator new

(SIZE_T

);

That is, it has only one parameter, only receives a size information. Our following code

int

* Pi

=

New

int

;

// The Same as int * pi = new int (); or int * pi = new int [1]; equivalent

int

* TPI

=

int

*)

Operator new

(

Sizeof

(

int

));

// attention: this line cannot pass compi1 you have define debug_new

int

* Pi

= TPI

;

Similarly, definition Debug_new, this statement begins with error:

Bitmap

* BMPHOTO

=

New bitmap

(Thumbnail_width

Thumbnail_height

Pixelformat24bpprgb

);

Equivalent to

Bitmap

* TBMPHOTO

Bitmap

*)

Operator new

(

Sizeof

(Bitmap

));

TBMPHOTO

-> Bitmap

(Thumbnail_width

Thumbnail_height

Pixelformat24bpprgb

);

// Initialize VariableBitmap

* BMPHOTO

= TBMPHOTO

;

But now, since Debug_New uses it is overloaded

Operator new:

Void

* AFX_CDECL

Operator new

(SIZE_T NSIZE

, LPCSTR LPSZFILENAME

,

Int nline

);

The above code is equivalent to:

Bitmap

* TBMPHOTO

Bitmap

*)

Operator new

(

Sizeof

(Bitmap

), __File__

, __LINE__

);

TBMPHOTO

-> BitmapBitmap

(Thumbnail_width

Thumbnail_height

Pixelformat24bpprgb

);

// Initialize VariableBitmap

* BMPHOTO

= TBMPHOTO

;

Go back and see GDIPLUS

in

Operator new declaration (in Gdiplusbase

in .h):

Class gdiplusbase

{

public

:

Void

(

Operator delete

) (

Void

* In_pvoid

) {

Dllexports

:: GDIPFREE

(In_Pvoid

}

Void

*

Operator new

(SIZE_T IN_SIZE

) {

Return DLLEXPORTS

:: GDIPALLOC

(in_size

}

Void

(

Operator delete

[])

Void

* In_pvoid

) {

Dllexports

:: GDIPFREE

(In_Pvoid

}

Void

*

Operator new

[]) (SIZE_T IN_SIZE

) {

Return DLLEXPORTS

:: GDIPALLOC

(in_size);}};

It is overloaded

Operator new, and no one can accommodate

3 parameters

Operator New, at the same time, based on the fact:

Different nomencartments (referring to overloading between global namespaces, parent class, subclasses, global and classes), the next level of namespace covers the definition of the previous level unless the call is called The definition of the last level.

Therefore, the overall redefined

Operator New cannot be used for Bitmap classes. Also because of this reason, the compiler will report:

Bitmap

* TBMPHOTO

Bitmap

*) Bitmap

::

Operator new

(

Sizeof

(Bitmap

), __File__

, __LINE__

);

Error C2660

:

'new'

: Function Does

NOT TAKE

3 parameters

I know this, I have to fix this problem, just give

Class Gdiplusbase multiple loads more

Operator new. Corrected

Class gdiplusbase is as follows:

#ifdef _Debug

Namespace gdiplus

{

Namespace Dllexports

{

#include

}

#ifndef _gdiplusbase_h #define _gdiplusbase_h

Class gdiplusbase

{

public

:

Void

(

Operator delete

) (

Void

* In_pvoid

) {

Dllexports

:: GDIPFREE

(In_Pvoid

}

Void

*

Operator new

(SIZE_T IN_SIZE

) {

Return DLLEXPORTS

:: GDIPALLOC

(in_size

}

Void

(

Operator delete

[])

Void

* In_pvoid

) {

Dllexports

:: GDIPFREE

(In_Pvoid

}

Void

*

Operator new

[]) (SIZE_T IN_SIZE

) {

Return DLLEXPORTS

:: GDIPALLOC

(in_size

}

Void

*

Operator new

(SIZE_T NSIZE)

, LPCSTR LPSZFILENAME

,

Int nline

) {

Return DLLEXPORTS

:: GDIPALLOC

(NSIZE)

}

Void

Operator delete

(

Void

* P

, LPCSTR LPSZFILENAME

,

Int nline

) {

Dllexports

:: GDIPFREE

(p

}};

#ndif // #ifndef _GdiplusBase_H

}

#ndif // #ifDef _debugok, the problem has been resolved, in fact this is just a heavy load

Operator new problem, but this problem has become a bit complicated because of Debug_new.

Finally, summarize it,

Operator new overload should be taken:

1.

New operator is not overloaded, it can be overloaded

Operator new.

New Operator first call

Operator New, then call the constructor (if any).

This behavior of New Operator is not overloaded, it can be overloaded is only

Operator New, that is, memory allocation.

2. Overload

Operator New is a very careful thing, and overloaded the MFC program or the system you have written.

When Operator New, you should pay attention to it, and you should pay attention to all the #include header files to be added before all Define, so as not to cause subsequent pairs.

The impact of NEW's redefinition. You can try #define in your MFC program

After new debug_new, add #include

>, You will receive a lot of inexplicable wonderful error tips (Debug compiles), this is because #define

New debug_new and behind

Static

Char this_file

[] = __File__

Caused by the impact.

3.

Operator new

/

Delete is similar to a static function in nature, you can access them directly through class names.

4. Understand

Operator New's basic concept, you must understand the Placement in the header file NEW

New

/

DELETE is not a difficult thing, the toppers in the header file NEW

New

/

DELETE is achieved as follows:

#ifndef __Placement_new_inline # define __placement_new_inline

inline

Void

* __ cdecl

Operator new

(SIZE_T

,

Void

* _P

) {

Return

(_P

}

#iF _MSC_VER> = 1200

inline

Void __cdecl

Operator delete

(

Void

*,

Void

*) {

Return

}

# ENDIF # ENDIF

Attachment:

(Reposted

) C

NEW Introduction

1.

New T

The first

New simplest

Calling class

If overloaded

) Or global

Operator new allocation space

, Then call the constructor with the parameters of the column column after the type

Usage

New TypeName

(Initial_Args_List

).

If there is no parameters

, Parentheses can generally omit

.E.g

int

* P

=

New

int

;

int

* P

=

New

int

(

10

);

int

* P

=

New foo

(

"hello"

);

Call

Delete is destroyed

:

Delete P

;

2.

New T

[]

This

New used to create a dynamic object array

He will call the object

Operator new

[] To allocate memory

(If you don't call

Operator new

, Search order

), Then call the 31M default constructor of the object to initialize each object usage

:

New TypeName

Num_of_Objects

];

E.g

int

* P

=

New

int

[

10

];

Use when destroy

Operator delete31m

[]

3.

New

() T and

New

() T

[]

This is a parameter

New

, This form

NEW will call

Operator new

(SIZE_T

Othertype

) To allocate memory

Here, Othertype is compatible with the type of parameters in New Braces.

This syntax is usually used in a particular address component object.

Placement, called Placement

New

Prerequisite

Operator new

(SIZE_T

,

Void

*) Has been defined

Usually the compiler has provided an implementation

,contain

<

New

> Head file

This implementation is simply returned to the specified address of the parameters.

,thus

New

() Operators will create objects on the address in parentheses

.

It should be noted

The second parameter is not necessarily

Void

*, Legitimate types that can be identified

, At this time

overload mechanism to determine the call

Operator new

.

of course

We can provide yourself

Operator new

(SIZE_

,Ys

)

NEW behavior

,such as

Char Data

[

1000

] [

Sizeof

(foo

)];

inline

Void

*

Operator new

(SIZE_T

,

Int n

) {

Return Data

[N

}

You can use such interesting syntax to create an object

:

foo

* P

=

New

(

6

) Foo

();

// Index to the Sixth Unit of the object in the sixth unit of DATA is really interesting in the standard library also provides a NothRow implementation

:

Void

*

Operator new

(STD

:: SIZE_T

,

Const STD

:: Nothrow_t

&)

Throw

();

Void

*

Operator new

[] (STD

:: SIZE_T

,

Const STD

:: Nothrow_t

&)

Throw

();

Call can be called

Does not throw an exception when the New fails

New

(nothrow

)

int

(

10

);

// Nothrow is an instance of std :: nothrow_t

Placement

NEW created objects cannot be directly

Delete is destroyed

Instead, to call the paid function of the object to destroy the object

How to deal with the memory occupied by the object

To see the specific source of this memory

.

4.

Operator new

(SIZE_T

)

This operator assigns parameters Specify the size of the memory and returns the first address.

, Can overload this operator for custom class

The method is to declare in the class

Void

*

Operator new

(SIZE_T SIZE

) {

/ / Allocate memory here and return its address

}

No matter whether it is declared

Various

Operator New and

Operator delete has

Static property

.

Never need to call directly

Operator new

Unless the original memory is directly assigned

(This is similar to the malloc of C

), In the conflict, call the global

Operator plus

:: Scope Operator

:::

Operator new

(

1000

);

// Allocate 1000 31M bytes

Returned memory needs to be recycled

Call corresponding

Operator delete

5.

Operator new

[] (SIZE_T

)

This is also allocated memory

,, Only is specifically for arrays

That is

New T

This form

,of course

, Can be explicitly called when needed

6.

Operator new

(SIZE_T SIZE

, Othertype Other_Value

)

with

Operator new

[] (SIZE_T SIZE

, Othertype Other_Value

)

See

New

()

Need to emphasize

,

NEW is used to create objects and allocate memory

It is not changeable

It can be changed.

Operator new

We can overload

Operator New to implement our memory allocation scheme

.

Reference:

1.prb

: Microsoft Foundation Classes Debug_new Does Not Work with GDI . Http

:

//support.microsoft.com/default.aspx?scid=kb;n-us; 317799

2.vc

6.0 memory leak detection

HTTP

:

//blog.vckbase.com/bruceteen/archive/2004/10/28/1130.aspx

3.More Effective C

. Item

8

: Understand the Different Meanings of

New and delete

.

转载请注明原文地址:https://www.9cbs.com/read-42262.html

New Post(0)