C++ 运算符重载new和delete获取编译器错误

C++ 运算符重载new和delete获取编译器错误,c++,compiler-errors,operator-overloading,new-operator,C++,Compiler Errors,Operator Overloading,New Operator,我试图执行一本编程书中关于“运算符重载”的代码示例。但是,我有以下错误: invalid conversion from 'char' to 'void*' [-fpermissive] char *p= new ('$') char[100]; 这就是我重载新操作符的方式: void *operator new(size_t sz,int setvalue) { void *p; p=malloc(sz); if(p==NULL){ me

我试图执行一本编程书中关于“运算符重载”的代码示例。但是,我有以下错误:

invalid conversion from 'char' to 'void*' [-fpermissive]
      char *p= new ('$') char[100];
这就是我重载新操作符的方式:

void *operator new(size_t sz,int setvalue)
{
    void *p;

    p=malloc(sz);
    if(p==NULL){
        memoryWarning();
    }
    memset(p,setvalue,sz);
    return(p);
}


int main()
{
    //rest of the code;
    char *p = new ('$') char[100];
    //rest of the code
}
生成期间的控制台输出:

21:39:21 **** Incremental Build of configuration Debug for project chapter5a ****
Info: Internal Builder is used for build
g++ -O0 -g3 -Wall -c -fmessage-length=0 -std=c99 -o "src\\chapter5a.o" "..\\src\\chapter5a.cpp" 
cc1plus.exe: warning: command line option '-std=c99' is valid for C/ObjC but not for C++
<strong>..\src\chapter5a.cpp: In function 'int main()':
..\src\chapter5a.cpp:22:20: error: invalid conversion from 'char' to 'void*' [-fpermissive]
  char *p= new('$') char;*
                    ^~~~</strong>
In file included from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/ext/new_allocator.h:33:0,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/i686-w64-mingw32/bits/c++allocator.h:33,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/bits/allocator.h:46,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/string:41,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/bits/locale_classes.h:40,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/bits/ios_base.h:41,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/ios:42,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/ostream:38,
                 from C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/iostream:39,
                 from ..\src\chapter5a.cpp:9:
C:/Program Files (x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/c++/new:146:14:<strong> note:   initializing argument 2 of 'void* operator new(std::size_t, void*)'
 inline void* operator new(std::size_t, void* __p) _GLIBCXX_USE_NOEXCEPT
              ^~~~~~~~</strong>

21:39:21 Build Finished (took 703ms)
21:39:21****项目第5A章配置调试增量构建****
信息:内部生成器用于生成
g++-O0-g3-Wall-c-fmessage length=0-std=c99-o“src\\chapter5a.o”“..\\src\\chapter5a.cpp”
Cc1Puls.EXE:警告:命令行选项'STD= C99 '对于C/Objc有效,但不适用于C++
。\src\chapter5a.cpp:在函数“int main()”中:
..\src\chapter5a.cpp:22:20:错误:从“char”到“void*”的转换无效[-fppermissive]
char*p=新(“$”)字符*
^~~~
在C:/ProgramFiles(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/ext/new_分配器中包含的文件中。h:33:0,
来自C:/ProgramFiles(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/i686-w64-mingw32/bits/C++分配器。h:33,
来自C:/ProgramFiles(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/bits/allocator.h:46,
来自C:/ProgramFiles(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/string:41,
来自C:/ProgramFiles(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/bits/locale_classes.h:40,
来自C:/Program Files(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/bits/ios_base.h:41,
来自C:/Program Files(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/ios:42,
来自C:/ProgramFiles(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/ostream:38,
来自C:/Program Files(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/iostream:39,
摘自..\src\chapter5a.cpp:9:
C:/ProgramFiles(x86)/mingw-w64/i686-6.4.0-posix-dwarf-rt_v5-rev0/mingw32/lib/gcc/i686-w64-mingw32/6.4.0/include/C++/new:146:14:注意:初始化'void*操作符new(std::size\u t,void*)的参数2
内联void*运算符新(std::size\u t,void*\u p)\u GLIBCXX\u使用\u无例外
^~~~~~~
21:39:21构建完成(耗时703ms)

您重载了错误的运算符

char *p = new ('$') char[100];
调用
运算符new[]
,而不是
运算符new
,因为它是一个数组新表达式

所以你想超载

void *operator new[](size_t sz,int setvalue)
不是

实际上,您可能应该同时重载这两个操作(您可以从
操作员新[]
调用
操作员新

当您分别重载
operator new
operator new[]
时,还需要始终重载
operator delete
operator delete[]

我不知道什么是
memoryWarning()
确实如此,但请注意,没有非抛出异常规范的
运算符new
(和
运算符new[]
)必须抛出一个异常,当分配失败时,
catch(std::bad_alloc)
可以捕获该异常。不允许返回空指针

最后,
操作符new
您试图在此处形成的重载无法按您希望的方式工作

malloc
不会在分配的内存中创建任何对象
memset
(如果这里技术上允许)将字符写入该内存。然后,新表达式将在该内存中创建
char
数组

新创建的对象不具有它们所在的内存以前具有的值。相反,数组的
char
元素的值将是不确定的,您需要再次初始化它们

正确的方法不是重载
运算符new
,而是手动初始化数组,最好不要使用C标准库函数
memset
,如果您没有充分的理由使用它的话。使用例如
std::fill
(需要
#include
):

或者更好地使用
std::string
(需要
#include
):

可以从
str.data()
获取指向底层
char
数组的指针



另外,不要使用
NULL
。由于C++11,所以有
nullptr
,使用起来总是更安全。切勿使用
NULL
,始终使用
NULL ptr

您的书似乎有缺陷。我推荐一种
main
应该返回
int
,合并
new
和。在VisualStudio中,它进行编译和工作。你能试着把行改成
char*p=(char*)(new(“$”)char[100])并查看它是否有效?你使用什么类型的编译器?我正在使用MinGW GCCTried将行更改为
char*p=(char*)(new(“$”)char[100])
它不起作用。同样的错误。@Rixment它似乎也适用于戈德博尔特上的MSVC(即使是
/permissive-
)。我不知道MSVC为什么认为它可以在这里调用
操作员新建
而不是
操作员新建[]
,而无需诊断。我在标准中找不到任何支持这一点的东西。在我看来,这是一个非标准的扩展或bug。
void *operator new(size_t sz,int setvalue)
char *p = new char[100];
std::fill(p, p+100, '$');
std::string str(100, '$');