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



我正在尝试执行一本编程书中关于"运算符重载"的代码示例。然而,我有以下错误:

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>..srcchapter5a.cpp: In function 'int main()':
..srcchapter5a.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 ..srcchapter5a.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)

您重载了错误的运算符。

char *p = new ('$') char[100];

调用operator new[],而不是operator new,因为它是一个数组新表达式。

所以你想让过载

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

不是

void *operator new(size_t sz,int setvalue)

在实践中,您可能应该使两者都过载(您可以从operator new[]调用opearator new(。

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

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

最后,你试图在这里形成的operator new过载并没有按照你想要的方式工作

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

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

在这里尝试的正确方法不是重载operator new,而是手动初始化数组,如果没有充分的理由使用C标准库函数memset,最好不要使用它。请使用例如std::fill(需要#include<algorithm>(:

char *p = new char[100];
std::fill(p, p+100, '$');

或者更好,使用std::string(需要#include<string>(:

std::string str(100, '$');

可以从CCD_ 25获得指向底层CCD_ 24阵列的指针。


此外,不要使用NULL。由于C++11存在nullptr,因此使用起来总是更安全。切勿使用NULL,始终使用nullptr

最新更新