couldn't compile OpenSSL example: EVP Symmetric Encryption and Decryption - c++

I'm building an encryption/decryption example from OpenSSL docs on CentOS7:
// g++ -Wall -std=c++11 evp-encrypt.cxx -o evp-encrypt.exe -lcrypto
#include <iostream>
#include <string>
#include <memory>
#include <limits>
#include <stdexcept>
#include <openssl/evp.h>
#include <openssl/rand.h>
static const unsigned int KEY_SIZE = 32;
static const unsigned int BLOCK_SIZE = 16;
template <typename T>
struct zallocator
{
public:
typedef T value_type;
typedef value_type* pointer;
typedef const value_type* const_pointer;
typedef value_type& reference;
typedef const value_type& const_reference;
typedef std::size_t size_type;
typedef std::ptrdiff_t difference_type;
pointer address (reference v) const {return &v;}
const_pointer address (const_reference v) const {return &v;}
pointer allocate (size_type n, const void* hint = 0) {
if (n > std::numeric_limits<size_type>::max() / sizeof(T))
throw std::bad_alloc();
return static_cast<pointer> (::operator new (n * sizeof (value_type)));
}
void deallocate(pointer p, size_type n) {
OPENSSL_cleanse(p, n*sizeof(T));
::operator delete(p);
}
size_type max_size() const {
return std::numeric_limits<size_type>::max() / sizeof (T);
}
template<typename U>
struct rebind
{
typedef zallocator<U> other;
};
void construct (pointer ptr, const T& val) {
new (static_cast<T*>(ptr) ) T (val);
}
void destroy(pointer ptr) {
static_cast<T*>(ptr)->~T();
}
#if __cpluplus >= 201103L
template<typename U, typename... Args>
void construct (U* ptr, Args&& ... args) {
::new (static_cast<void*> (ptr) ) U (std::forward<Args> (args)...);
}
template<typename U>
void destroy(U* ptr) {
ptr->~U();
}
#endif
};
typedef unsigned char byte;
typedef std::basic_string<char, std::char_traits<char>, zallocator<char> > secure_string;
using EVP_CIPHER_CTX_free_ptr = std::unique_ptr<EVP_CIPHER_CTX, decltype(&::EVP_CIPHER_CTX_free)>;
void gen_params(byte key[KEY_SIZE], byte iv[BLOCK_SIZE]);
void aes_encrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const secure_string& ptext, secure_string& ctext);
void aes_decrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const secure_string& ctext, secure_string& rtext);
// g++ -Wall -std=c++11 evp-encrypt.cxx -o evp-encrypt.exe -lcrypto
int main(int argc, char* argv[])
{
// Load the necessary cipher
EVP_add_cipher(EVP_aes_256_cbc());
// plaintext, ciphertext, recovered text
secure_string ptext = "Now is the time for all good men to come to the aide of their country";
secure_string ctext, rtext;
byte key[KEY_SIZE], iv[BLOCK_SIZE];
gen_params(key, iv);
aes_encrypt(key, iv, ptext, ctext);
aes_decrypt(key, iv, ctext, rtext);
OPENSSL_cleanse(key, KEY_SIZE);
OPENSSL_cleanse(iv, BLOCK_SIZE);
std::cout << "Original message:\n" << ptext << std::endl;
std::cout << "Recovered message:\n" << rtext << std::endl;
return 0;
}
void gen_params(byte key[KEY_SIZE], byte iv[BLOCK_SIZE])
{
int rc = RAND_bytes(key, KEY_SIZE);
if (rc != 1)
throw std::runtime_error("RAND_bytes key failed");
rc = RAND_bytes(iv, BLOCK_SIZE);
if (rc != 1)
throw std::runtime_error("RAND_bytes for iv failed");
}
void aes_encrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const secure_string& ptext, secure_string& ctext)
{
EVP_CIPHER_CTX_free_ptr ctx(EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free);
int rc = EVP_EncryptInit_ex(ctx.get(), EVP_aes_256_cbc(), NULL, key, iv);
if (rc != 1)
throw std::runtime_error("EVP_EncryptInit_ex failed");
// Recovered text expands upto BLOCK_SIZE
ctext.resize(ptext.size()+BLOCK_SIZE);
int out_len1 = (int)ctext.size();
rc = EVP_EncryptUpdate(ctx.get(), (byte*)&ctext[0], &out_len1, (const byte*)&ptext[0], (int)ptext.size());
if (rc != 1)
throw std::runtime_error("EVP_EncryptUpdate failed");
int out_len2 = (int)ctext.size() - out_len1;
rc = EVP_EncryptFinal_ex(ctx.get(), (byte*)&ctext[0]+out_len1, &out_len2);
if (rc != 1)
throw std::runtime_error("EVP_EncryptFinal_ex failed");
// Set cipher text size now that we know it
ctext.resize(out_len1 + out_len2);
}
void aes_decrypt(const byte key[KEY_SIZE], const byte iv[BLOCK_SIZE], const secure_string& ctext, secure_string& rtext)
{
EVP_CIPHER_CTX_free_ptr ctx(EVP_CIPHER_CTX_new(), ::EVP_CIPHER_CTX_free);
int rc = EVP_DecryptInit_ex(ctx.get(), EVP_aes_256_cbc(), NULL, key, iv);
if (rc != 1)
throw std::runtime_error("EVP_DecryptInit_ex failed");
// Recovered text contracts upto BLOCK_SIZE
rtext.resize(ctext.size());
int out_len1 = (int)rtext.size();
rc = EVP_DecryptUpdate(ctx.get(), (byte*)&rtext[0], &out_len1, (const byte*)&ctext[0], (int)ctext.size());
if (rc != 1)
throw std::runtime_error("EVP_DecryptUpdate failed");
int out_len2 = (int)rtext.size() - out_len1;
rc = EVP_DecryptFinal_ex(ctx.get(), (byte*)&rtext[0]+out_len1, &out_len2);
if (rc != 1)
throw std::runtime_error("EVP_DecryptFinal_ex failed");
// Set recovered text size now that we know it
rtext.resize(out_len1 + out_len2);
}
When compiling it with g++ -Wall -std=c++11 evp-encrypt.cxx -o evp-encrypt.exe -lcrypto, g++ reports:
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.tcc:568:28: error: no match for 'operator==' (operand types are 'const zallocator<char>' and 'zallocator<char>')
if (__beg == __end && __a == _Alloc())
~~~~^~~~~~~~~~~
more error info:
In file included from /opt/rh/devtoolset-7/root/usr/include/c++/7/string:53:0,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/locale_classes.h:40,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/bits/ios_base.h:41,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/ios:42,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/ostream:38,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/iostream:39,
from evp-encrypt.cpp:1:
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.tcc: In instantiation of 'static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&, std::forward_iterator_tag) [with _FwdIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = zallocator<char>]':
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:5033:30: required from 'static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct_aux(_InIterator, _InIterator, const _Alloc&, std::__false_type) [with _InIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = zallocator<char>]'
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.h:5054:27: required from 'static _CharT* std::basic_string<_CharT, _Traits, _Alloc>::_S_construct(_InIterator, _InIterator, const _Alloc&) [with _InIterator = const char*; _CharT = char; _Traits = std::char_traits<char>; _Alloc = zallocator<char>]'
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.tcc:664:31: required from 'std::basic_string<_CharT, _Traits, _Alloc>::basic_string(const _CharT*, const _Alloc&) [with _CharT = char; _Traits = std::char_traits<char>; _Alloc = zallocator<char>]'
evp-encrypt.cpp:85:27: required from here
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/basic_string.tcc:568:28: error: no match for 'operator==' (operand types are 'const zallocator<char>' and 'zallocator<char>')
if (__beg == __end && __a == _Alloc())
~~~~^~~~~~~~~~~
In file included from /opt/rh/devtoolset-7/root/usr/include/c++/7/iosfwd:40:0,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/ios:38,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/ostream:38,
from /opt/rh/devtoolset-7/root/usr/include/c++/7/iostream:39,
from evp-encrypt.cpp:1:
/opt/rh/devtoolset-7/root/usr/include/c++/7/bits/postypes.h:216:5: note: candidate: template<class _StateT> bool std::operator==(const std::fpos<_StateT>&, const std::fpos<_StateT>&)
operator==(const fpos<_StateT>& __lhs, const fpos<_StateT>& __rhs)
^~~~~~~~
How do I fix it to get it working?
environment:
g++ (GCC) 7.3.1 20180303 (Red Hat 7.3.1-5)
OpenSSL version: 1.1.1-pre5-dev

Here the error: https://godbolt.org/z/7fGh3qGeM
Compiled with GCC 5.1 https://godbolt.org/z/EbsKzGb34
You need to update your GCC.

Related

c++ boost raw socket setup

I'm doing some small project, trying to setup RAW socket, proof of concept program just to get socket up and running:
io.hpp:
#pragma once
#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>
#include <net/ethernet.h>
#include <sys/socket.h>
#include <linux/if_packet.h>
// change max length to bytes received
template <typename Protocol>
class ll_endpoint
{
private:
sockaddr_ll sockaddr;
public:
typedef Protocol protocol_type;
typedef boost::asio::detail::socket_addr_type data_type;
ll_endpoint(char* ifname)
{
sockaddr.sll_family = PF_PACKET;
sockaddr.sll_protocol = htons(ETH_P_ALL);
sockaddr.sll_ifindex = if_nametoindex(ifname);
sockaddr.sll_hatype = 1;
}
ll_endpoint& operator=(const ll_endpoint& other)
{
sockaddr = other.sockaddr;
return *this;
}
protocol_type protocol() const
{
return protocol_type();
}
data_type* data()
{
return (struct sockaddr*)&sockaddr;
}
const data_type* data() const
{
return (struct sockaddr*)&sockaddr;
}
std::size_t size() const
{
return sizeof(sockaddr);
}
void resize(std::size_t size)
{
/* nothing we can do here */
}
std::size_t capacity() const
{
return sizeof(sockaddr);
}
friend bool operator==(const ll_endpoint<Protocol>& e1,
const ll_endpoint<Protocol>& e2)
{
return ( e1.sockaddr.sll_addr == e2.sockaddr.sll_addr );
}
friend bool operator!=(const ll_endpoint<Protocol>& e1,
const ll_endpoint<Protocol>& e2)
{
return !(e1.sockaddr.sll_addr == e2.sockaddr.sll_addr);
}
friend bool operator<(const ll_endpoint<Protocol>& e1,
const ll_endpoint<Protocol>& e2)
{
return e1.sockaddr.sll_addr < e2.sockaddr.sll_addr;
}
friend bool operator>(const ll_endpoint<Protocol>& e1,
const ll_endpoint<Protocol>& e2)
{
return e2.sockaddr.sll_addr < e1.sockaddr.sll_addr;
}
friend bool operator<=(const ll_endpoint<Protocol>& e1,
const ll_endpoint<Protocol>& e2)
{
return !(e2 < e1);
}
friend bool operator>=(const ll_endpoint<Protocol>& e1,
const ll_endpoint<Protocol>& e2)
{
return !(e1 < e2);
}
};
class ll_protocol
{
public:
typedef boost::asio::basic_raw_socket<ll_protocol> socket;
typedef ll_endpoint<ll_protocol> endpoint;
int type() const {
return SOCK_RAW;
}
int protocol() const {
return protocol_;
}
int family() const{
return family_;
}
ll_protocol(int protocol, int family): protocol_(protocol), family_(family) {}
ll_protocol(): protocol_(htons(ETH_P_ALL)), family_(PF_PACKET) {}
private:
int protocol_;
int family_;
};
class IO {
typedef boost::asio::basic_raw_socket<ll_protocol> socket;
typedef ll_endpoint<ll_protocol> endpoint;
public:
IO(boost::asio::io_context& io_context, char* ifname)
: socket_(io_context, ll_endpoint<ll_protocol>(ifname))
{
do_receive();
}
void do_receive()
{
socket_.async_receive_from(
boost::asio::buffer(data_, max_length), sender_endpoint_,
[this](boost::system::error_code ec, std::size_t bytes_recvd) // <--- handler
{
if (!ec && bytes_recvd > 0)
{
do_send(bytes_recvd);
}
else
{
do_receive();
}
});
}
void do_send(std::size_t length)
{
socket_.async_send_to(
boost::asio::buffer(data_, length), sender_endpoint_,
[this](boost::system::error_code /*ec*/, std::size_t /*bytes_sent*/)
{
do_receive();
});
}
private:
socket socket_;
endpoint sender_endpoint_;
enum { max_length = 9000 };
char data_[max_length]; // change to vector?, const std::vector<uint8_t>& packet
};
Main.cpp
#include <cctype>
#include <cstdlib>
#include <iostream>
#include <boost/asio.hpp>
#include "io.hpp"
int main(int argc, char *argv[]) {
try
{
boost::asio::io_context io_context;
IO s(io_context, argv[1]);
io_context.run();
}
catch (std::exception& e)
{
std::cerr << "Exception: " << e.what() << "\n";
}
return 0;
}
On compile I get this error:
io.hpp:142:56: error: expected primary-expression before ‘>’ token
142 | : socket_(io_context, sender_endpoint_<ll_protocol>(ifname))
| ^
io.hpp:142:65: error: no matching function for call to ‘ll_endpoint<ll_protocol>::ll_endpoint()’
142 | : socket_(io_context, sender_endpoint_<ll_protocol>(ifname))
| ^
io.hpp:25:5: note: candidate: ‘ll_endpoint<Protocol>::ll_endpoint(const char*) [with Protocol = ll_protocol]’
25 | ll_endpoint(const char* ifname)
| ^~~~~~~~~~~
io.hpp:25:5: note: candidate expects 1 argument, 0 provided <--- but why *thanks Useless for spotting this, however even I pass something error is the same
Is it a template misuse and what I am missing?
expectation is to setup socket in a similar way to https://www.boost.org/doc/libs/1_70_0/doc/html/boost_asio/example/cpp11/echo/async_udp_echo_server.cpp
The member variable sender_endpoint_ have the type endpoint, which is an alias of ll_endpoint<ll_protocol>.
The type endpoint is a concrete type, it's not a template. So adding template-arguments for sender_endpoint_ makes no sense.
Just remove the template-arguments: sender_endpoint_(ifname)

Difference in compiling for ubuntu and for Mac

I have written program to work like a telephone operator for TCP clients.
A TCP client connects to the server, and then gives a channel name to the server.
If another TCP client connect to the server and give the same channel name, the server connects the 2 TCP clients together, allowing them to talk to each other without interference.
When I compile this on Mac, it works fine, but when I put it on a digital ocean droplet, I get this error during compilation. I have generated the makefile using netbeans.
This is StreamSwitch.h
#ifndef STREAMSWITCH_H
#define STREAMSWITCH_H
#include <string>
#include <sstream>
#include <iostream>
#include <list>
using namespace std;
struct Comparator{
int length;
uint8_t *pointer;
};
class DiscriptorNode{
public:
int FileDiscriptor;
uint8_t ChannelName[1000];
bool operator == (const DiscriptorNode& s) const { return (this->FileDiscriptor) == (s.FileDiscriptor); }
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
bool operator != (const DiscriptorNode& s) const { return !operator==(s); }
};
class StreamConnection{
public:
int FileDiscriptors[2];
bool operator == (const StreamConnection& s) const { return this->FileDiscriptors == s.FileDiscriptors; }
bool operator != (const StreamConnection& s) const { return !operator==(s); }
};
class StreamSwitch{
list <DiscriptorNode> Unconnected;
list <StreamConnection> Connected;
int ServerFileDiscriptor;
int PortNumber;
string ErrorMessage;
public:
StreamSwitch(int portNumber);
void HandleCommunication();
bool Begin();
string GetError();
};
#endif /* STREAMSWITCH_H */
This is StreamSwitch.cpp
#include "StreamSwitch.h"
#include <sys/socket.h>
#include <netinet/in.h>
#include <cstdlib>
#include <iostream>
#include <sys/select.h>
#include <unistd.h>
void remove(list<DiscriptorNode> List, list<DiscriptorNode>:: iterator &Iterator){
list<DiscriptorNode> ::iterator temp=Iterator;
Iterator++;
List.erase(temp);
}
void remove(list<StreamConnection> List, list<StreamConnection>:: iterator &Iterator){
list<StreamConnection> ::iterator temp=Iterator;
Iterator++;
List.erase(temp);
}
StreamSwitch::StreamSwitch(int portNumber) {
this->PortNumber=portNumber;
}
bool StreamSwitch::Begin(){
int ReUseSocket=1;
struct sockaddr_in ServerAddress;
this->ServerFileDiscriptor=socket(AF_INET, SOCK_STREAM, 0);
bzero((char *) &ServerAddress, sizeof (ServerAddress));
ServerAddress.sin_family = AF_INET;
ServerAddress.sin_port = htons(PortNumber);
ServerAddress.sin_addr.s_addr = INADDR_ANY;
if (setsockopt(this->ServerFileDiscriptor, SOL_SOCKET, SO_REUSEADDR, &ReUseSocket, sizeof (ReUseSocket)) == 1) {
return 1;
}
if (bind(this->ServerFileDiscriptor, (struct sockaddr *) &ServerAddress, sizeof (ServerAddress)) < 0) {
std::stringstream ss;
ss<<"Could not bind, port "<<this->PortNumber<<" is being used";
this->ErrorMessage=ss.str();
return false;
}
listen(this->ServerFileDiscriptor, 1024);
return true;
}
uint8_t InputDataBuffer[1000];
void StreamSwitch::HandleCommunication(){
int maximumFd=0;
struct timeval Timer_Variable;
list<DiscriptorNode> ::iterator DiscIterator;
list<StreamConnection> ::iterator ConnectionIterator;
fd_set ReadFileDiscriptors, ExceptFileDiscriptors, WriteFileDiscriptors;
Timer_Variable.tv_sec = 0;
Timer_Variable.tv_usec = 100;
FD_ZERO(&ReadFileDiscriptors);
FD_ZERO(&WriteFileDiscriptors);
FD_ZERO(&ExceptFileDiscriptors);
FD_SET(this->ServerFileDiscriptor, &ReadFileDiscriptors);
FD_SET(this->ServerFileDiscriptor, &WriteFileDiscriptors);
FD_SET(this->ServerFileDiscriptor, &ExceptFileDiscriptors);
if (maximumFd<this->ServerFileDiscriptor) {
maximumFd = this->ServerFileDiscriptor;
}
for (DiscIterator = this->Unconnected.begin(); DiscIterator != this->Unconnected.end(); DiscIterator++) {
FD_SET((*DiscIterator).FileDiscriptor, &ReadFileDiscriptors);
FD_SET((*DiscIterator).FileDiscriptor, &WriteFileDiscriptors);
FD_SET((*DiscIterator).FileDiscriptor, &ExceptFileDiscriptors);
if (maximumFd < (*DiscIterator).FileDiscriptor) {
maximumFd = (*DiscIterator).FileDiscriptor;
}
}
for (ConnectionIterator = this->Connected.begin(); ConnectionIterator != this->Connected.end(); ConnectionIterator++) {
for (int i = 0; i < 2; i++) {
FD_SET((*ConnectionIterator).FileDiscriptors[i], &ReadFileDiscriptors);
FD_SET((*ConnectionIterator).FileDiscriptors[i], &WriteFileDiscriptors);
FD_SET((*ConnectionIterator).FileDiscriptors[i], &ExceptFileDiscriptors);
if (maximumFd < (*ConnectionIterator).FileDiscriptors[i]) {
maximumFd = (*ConnectionIterator).FileDiscriptors[i];
}
}
}
maximumFd++;
select(maximumFd,&ReadFileDiscriptors,&WriteFileDiscriptors,&ExceptFileDiscriptors,&Timer_Variable);
if(FD_ISSET(this->ServerFileDiscriptor,&ReadFileDiscriptors)){
struct sockaddr_in ClientAddress;
DiscriptorNode node;
socklen_t clientLength=sizeof(ClientAddress);
node.FileDiscriptor=accept(this->ServerFileDiscriptor, (struct sockaddr *) &ClientAddress, &clientLength);
cout<<"Got a new connection"<<endl;
bzero(node.ChannelName,sizeof(node.ChannelName));
this->Unconnected.push_back(node);
}
for (DiscIterator = this->Unconnected.begin(); DiscIterator != this->Unconnected.end(); DiscIterator++) {
if(FD_ISSET((*DiscIterator).FileDiscriptor,&ExceptFileDiscriptors)){
close((*DiscIterator).FileDiscriptor);
remove(this->Unconnected,DiscIterator);
continue;
}
int errorsoc = 0;
socklen_t len = sizeof (errorsoc);
int retval = getsockopt((*DiscIterator).FileDiscriptor
, SOL_SOCKET
, SO_ERROR
, &errorsoc
, &len);
if ((retval != 0) || (errorsoc != 0)) {
close((*DiscIterator).FileDiscriptor);
remove(this->Unconnected,DiscIterator);
continue;
}
if(FD_ISSET((*DiscIterator).FileDiscriptor,&ReadFileDiscriptors)){
int TransferCount;
bzero(InputDataBuffer,sizeof(InputDataBuffer));
TransferCount=read((*DiscIterator).FileDiscriptor, InputDataBuffer, sizeof(InputDataBuffer));
if (TransferCount < 1) {
close((*DiscIterator).FileDiscriptor);
remove(this->Unconnected,DiscIterator);
continue;
}
Comparator s;
cout<<"Got this data "<<InputDataBuffer<<endl;
s.pointer=InputDataBuffer;
s.length=TransferCount;
list<DiscriptorNode>::iterator matching=std::find(this->Unconnected.begin(),this->Unconnected.end(),s);
if(matching==this->Unconnected.end()){
cout<<"Did not find matching"<<endl;
memcpy((*DiscIterator).ChannelName,InputDataBuffer,TransferCount);
continue;
}
cout<<"Matched "<<InputDataBuffer<<endl;
StreamConnection connect;
connect.FileDiscriptors[0]=(*matching).FileDiscriptor;
connect.FileDiscriptors[1]=(*DiscIterator).FileDiscriptor;
remove(this->Unconnected,matching);
remove(this->Unconnected,DiscIterator);
this->Connected.push_back(connect);
}
}
for (ConnectionIterator = this->Connected.begin(); ConnectionIterator != this->Connected.end(); ConnectionIterator++) {
for (int i = 0; i < 2; i++) {
if (FD_ISSET((*ConnectionIterator).FileDiscriptors[i], &ExceptFileDiscriptors)) {
close((*ConnectionIterator).FileDiscriptors[i]);
close((*ConnectionIterator).FileDiscriptors[1-i]);
remove(this->Connected,ConnectionIterator);
break;
}
int errorsoc = 0;
socklen_t len = sizeof (errorsoc);
int retval = getsockopt((*ConnectionIterator).FileDiscriptors[i]
, SOL_SOCKET
, SO_ERROR
, &errorsoc
, &len);
if ((retval != 0) || (errorsoc != 0)) {
close((*ConnectionIterator).FileDiscriptors[i]);
close((*ConnectionIterator).FileDiscriptors[1-i]);
remove(this->Connected,ConnectionIterator);
break;
}
if (FD_ISSET((*ConnectionIterator).FileDiscriptors[i], &ReadFileDiscriptors)) {
int TransferCount;
bzero(InputDataBuffer, sizeof (InputDataBuffer));
TransferCount = read((*ConnectionIterator).FileDiscriptors[i], InputDataBuffer, sizeof (InputDataBuffer));
if (TransferCount < 1) {
close((*ConnectionIterator).FileDiscriptors[i]);
close((*ConnectionIterator).FileDiscriptors[1 - i]);
remove(this->Connected,ConnectionIterator);
break;
}
// cout<<"This is the data received "<<InputDataBuffer<<endl;
write((*ConnectionIterator).FileDiscriptors[1-i],InputDataBuffer,TransferCount);
}
}
}
}
string StreamSwitch::GetError(){
return this->ErrorMessage;
}
And this is my main
#include <list>
#include <cstdlib>
#include <iostream>
#include <unistd.h>
#include "StreamSwitch.h"
using namespace std;
/*
*
*/
int main(int argc, char** argv) {
StreamSwitch switcher(1234);
bool success=switcher.Begin();
if(!success){
cout<<switcher.GetError();
return 0;
}
while(1){
switcher.HandleCommunication();
usleep(1000);
}
return 0;
}
I have checked my make file and confirmed that it runs the following commands for compilation
g++ -c -g -MMD -MP -MF "build/Debug/GNU-MacOSX/StreamSwitch.o.d" -o build/Debug/GNU-MacOSX/StreamSwitch.o StreamSwitch.cpp
mkdir -p dist/Debug/GNU-MacOSX
g++ -o dist/Debug/GNU-MacOSX/streamswitch build/Debug/GNU-MacOSX/StreamSwitch.o build/Debug/GNU-MacOSX/main.o
This is the error I get on digital ocean droplet
g++ -c -g -MMD -MP -MF "build/Debug/GNU-MacOSX/StreamSwitch.o.d" -o build/Debug/GNU-MacOSX/StreamSwitch.o StreamSwitch.cpp
In file included from StreamSwitch.cpp:7:0:
StreamSwitch.h:23:5: error: ‘uint8_t’ does not name a type
uint8_t *pointer;
^
StreamSwitch.h:28:5: error: ‘uint8_t’ does not name a type
uint8_t ChannelName[1000];
^
StreamSwitch.h: In member function ‘bool DiscriptorNode::operator==(const Comparator&) const’:
StreamSwitch.h:30:68: error: ‘const struct Comparator’ has no member named ‘pointer’
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
^
StreamSwitch.h:30:82: error: ‘const class DiscriptorNode’ has no member named ‘ChannelName’
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
^
StreamSwitch.h:30:102: error: ‘memcmp’ was not declared in this scope
bool operator == (const Comparator& s) const { return memcmp(s.pointer,this->ChannelName,s.length)==0; }
^
StreamSwitch.cpp: In member function ‘bool StreamSwitch::Begin()’:
StreamSwitch.cpp:34:58: error: ‘bzero’ was not declared in this scope
bzero((char *) &ServerAddress, sizeof (ServerAddress));
^
StreamSwitch.cpp: In member function ‘void StreamSwitch::HandleCommunication()’:
StreamSwitch.cpp:95:20: error: ‘class DiscriptorNode’ has no member named ‘ChannelName’
bzero(node.ChannelName,sizeof(node.ChannelName));
^
StreamSwitch.cpp:95:44: error: ‘class DiscriptorNode’ has no member named ‘ChannelName’
bzero(node.ChannelName,sizeof(node.ChannelName));
^
StreamSwitch.cpp:95:56: error: ‘bzero’ was not declared in this scope
bzero(node.ChannelName,sizeof(node.ChannelName));
^
StreamSwitch.cpp:119:58: error: ‘bzero’ was not declared in this scope
bzero(InputDataBuffer,sizeof(InputDataBuffer));
^
StreamSwitch.cpp:128:15: error: ‘struct Comparator’ has no member named ‘pointer’
s.pointer=InputDataBuffer;
^
StreamSwitch.cpp:130:114: error: no matching function for call to ‘find(std::list<DiscriptorNode>::iterator, std::list<DiscriptorNode>::iterator, Comparator&)’
list<DiscriptorNode>::iterator matching=std::find(this->Unconnected.begin(),this->Unconnected.end(),s);
^
StreamSwitch.cpp:130:114: note: candidate is:
In file included from /usr/include/c++/4.8/bits/locale_facets.h:48:0,
from /usr/include/c++/4.8/bits/basic_ios.h:37,
from /usr/include/c++/4.8/ios:44,
from /usr/include/c++/4.8/istream:38,
from /usr/include/c++/4.8/sstream:38,
from StreamSwitch.h:17,
from StreamSwitch.cpp:7:
/usr/include/c++/4.8/bits/streambuf_iterator.h:369:5: note: template<class _CharT2> typename __gnu_cxx::__enable_if<std::__is_char<_CharT2>::__value, std::istreambuf_iterator<_CharT> >::__type std::find(std::istreambuf_iterator<_CharT>, std::istreambuf_iterator<_CharT>, const _CharT2&)
find(istreambuf_iterator<_CharT> __first,
^
/usr/include/c++/4.8/bits/streambuf_iterator.h:369:5: note: template argument deduction/substitution failed:
StreamSwitch.cpp:130:114: note: ‘std::_List_iterator<DiscriptorNode>’ is not derived from ‘std::istreambuf_iterator<_CharT>’
list<DiscriptorNode>::iterator matching=std::find(this->Unconnected.begin(),this->Unconnected.end(),s);
^
StreamSwitch.cpp:133:40: error: ‘class DiscriptorNode’ has no member named ‘ChannelName’
memcpy((*DiscIterator).ChannelName,InputDataBuffer,TransferCount);
^
StreamSwitch.cpp:133:81: error: ‘memcpy’ was not declared in this scope
memcpy((*DiscIterator).ChannelName,InputDataBuffer,TransferCount);
^
StreamSwitch.cpp:168:64: error: ‘bzero’ was not declared in this scope
bzero(InputDataBuffer, sizeof (InputDataBuffer));
^
Please help me figure out how to fix this for ubuntu, and I would love it if someone could explain how I can avoid this issue in the future.
Edited:
I fixed the issue by adding the following headers in StreamSwitch.h
#include <string.h>
#include <algorithm>
#include <inttypes.h>
and removing the following from StreamSwitch.h
#include <string>
I still don't know what is going on, or why code compiled on Mac and not on the digital Ocean droplet, or how I can avoid this issue all-together in the future.
The fixed width standard types appeared in C99 and C++11, see
http://en.cppreference.com/w/c/types/integer
http://en.cppreference.com/w/cpp/types/integer
They are declared/defined in "" and "".
So two steps to take to solve you problem platofrm independently is
1) #include <stdint.h> or #include <stdint>
2) make sure to compile by C99 or C++11 standards,
which might need to use special comandline parameters,
to be looked up in the documentation/help of your compilers
Note:
I extended an initially C answer to cover both. The C tag has been removed meanwhile. I think keeping the info on C is worth/harmless.

How do I return a boost::python::tuple containing a PyObject*?

I currently have a boost.python class that I use to acquire images from a basler camera convert them to opencv images and return them as numpy arrays for a python script.
I originally had the following code which worked:
PyObject *capture()
{
PyObject * ret;
CGrabResultPtr ptrGrabResult;
CPylonImage pylonImage;
Mat image;
//timer t;
try
{
// Set timer to 0
//t.reset();
// get a pointer to pylon image
camera->RetrieveResult( 50000, ptrGrabResult, TimeoutHandling_ThrowException);
// Get dimensions of image
int imageWidthPixels = ptrGrabResult->GetWidth();
int imageHeightPixels = ptrGrabResult->GetHeight();
if (ptrGrabResult->GrabSucceeded())
{
// Convert Grab result from YUV422 to BGR8
formatConverter->Convert(pylonImage, ptrGrabResult);
// Convert pylon image to opencv image
image = Mat(imageHeightPixels, imageWidthPixels, CV_8UC3, (std::uint8_t *) pylonImage.GetBuffer());
// Convert opencv image to PyObject
ret = pbcvt::fromMatToNDArray(image);
return ret;
}
else
{
//cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
}
}
catch (const GenericException &e)
{
// Error handling.
cerr << "An exception occurred." << endl
<< e.GetDescription() << endl;
}
// Return empty image if acquisition failed
return pbcvt::fromMatToNDArray(Mat());
}
However I would like to emulate the way opencv's VideoCapture functions and return a tuple
As such I naively altered the code thusly:
boost::python::tuple capture()
{
PyObject * ret;
CGrabResultPtr ptrGrabResult;
CPylonImage pylonImage;
Mat image;
//timer t;
try
{
// Set timer to 0
//t.reset();
// get a pointer to pylon image
camera->RetrieveResult( 50000, ptrGrabResult, TimeoutHandling_ThrowException);
// Get dimensions of image
int imageWidthPixels = ptrGrabResult->GetWidth();
int imageHeightPixels = ptrGrabResult->GetHeight();
if (ptrGrabResult->GrabSucceeded())
{
// Convert Grab result from YUV422 to BGR8
formatConverter->Convert(pylonImage, ptrGrabResult);
// Convert pylon image to opencv image
image = Mat(imageHeightPixels, imageWidthPixels, CV_8UC3, (std::uint8_t *) pylonImage.GetBuffer());
// Convert opencv image to PyObject
ret = pbcvt::fromMatToNDArray(image);
return boost::python::make_tuple(true, ret);
}
else
{
//cout << "Error: " << ptrGrabResult->GetErrorCode() << " " << ptrGrabResult->GetErrorDescription() << endl;
}
}
catch (const GenericException &e)
{
// Error handling.
cerr << "An exception occurred." << endl
<< e.GetDescription() << endl;
}
// Return opencv image
return boost::python::make_tuple(false, pbcvt::fromMatToNDArray(Mat()));
}
But when I attempt to compile I get the following error:
In file included from /usr/include/boost/python/call.hpp:15:0,
from /usr/include/boost/python/object_core.hpp:14,
from /usr/include/boost/python/args.hpp:25,
from /usr/include/boost/python.hpp:11,
from /home/anand/docker/pybasler/src/pyBasler.cpp:3:
/usr/include/boost/python/converter/arg_to_python.hpp: In instantiation of ‘static void boost::python::converter::detail::reject_raw_object_helper<T, Convertibility>::error(Convertibility) [with T = _object; Convertibility = char*]’:
/usr/include/boost/python/converter/arg_to_python.hpp:189:57: required from ‘void boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = _object]’
/usr/include/boost/python/converter/arg_to_python.hpp:217:36: required from ‘boost::python::converter::detail::pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr) [with Ptr = _object*]’
/usr/include/boost/python/converter/arg_to_python.hpp:256:13: required from ‘boost::python::converter::arg_to_python<T>::arg_to_python(const T&) [with T = _object*]’
/usr/include/boost/python/object_core.hpp:292:44: required from ‘static PyObject* boost::python::api::object_initializer_impl<is_proxy, is_object_manager>::get(const T&, mpl_::false_) [with T = _object*; bool is_proxy = false; bool is_object_manager = false; PyObject = _object; mpl_::false_ = mpl_::bool_<false>]’
/usr/include/boost/python/object_core.hpp:235:13: required from ‘PyObject* boost::python::api::object_base_initializer(const T&) [with T = _object*; PyObject = _object]’
/usr/include/boost/python/object_core.hpp:250:46: required from ‘boost::python::api::object::object(const T&) [with T = _object*]’
/usr/include/boost/python/detail/make_tuple.hpp:25:9: required from ‘boost::python::tuple boost::python::make_tuple(const A0&, const A1&) [with A0 = bool; A1 = _object*]’
/home/anand/docker/pybasler/src/pyBasler.cpp:130:63: required from here
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~^~
/usr/include/boost/python/converter/arg_to_python.hpp: In instantiation of ‘static void boost::python::converter::detail::reject_raw_object_helper<T, Convertibility>::error(Convertibility) [with T = _object; Convertibility = int*]’:
/usr/include/boost/python/converter/arg_to_python.hpp:194:56: required from ‘void boost::python::converter::detail::reject_raw_object_ptr(T*) [with T = _object]’
/usr/include/boost/python/converter/arg_to_python.hpp:217:36: required from ‘boost::python::converter::detail::pointer_deep_arg_to_python<Ptr>::pointer_deep_arg_to_python(Ptr) [with Ptr = _object*]’
/usr/include/boost/python/converter/arg_to_python.hpp:256:13: required from ‘boost::python::converter::arg_to_python<T>::arg_to_python(const T&) [with T = _object*]’
/usr/include/boost/python/object_core.hpp:292:44: required from ‘static PyObject* boost::python::api::object_initializer_impl<is_proxy, is_object_manager>::get(const T&, mpl_::false_) [with T = _object*; bool is_proxy = false; bool is_object_manager = false; PyObject = _object; mpl_::false_ = mpl_::bool_<false>]’
/usr/include/boost/python/object_core.hpp:235:13: required from ‘PyObject* boost::python::api::object_base_initializer(const T&) [with T = _object*; PyObject = _object]’
/usr/include/boost/python/object_core.hpp:250:46: required from ‘boost::python::api::object::object(const T&) [with T = _object*]’
/usr/include/boost/python/detail/make_tuple.hpp:25:9: required from ‘boost::python::tuple boost::python::make_tuple(const A0&, const A1&) [with A0 = bool; A1 = _object*]’
/home/anand/docker/pybasler/src/pyBasler.cpp:130:63: required from here
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
CMakeFiles/pbcvt.dir/build.make:62 : la recette pour la cible « CMakeFiles/pbcvt.dir/src/pyBasler.cpp.o » a échouée
make[2]: *** [CMakeFiles/pbcvt.dir/src/pyBasler.cpp.o] Erreur 1
CMakeFiles/Makefile2:67 : la recette pour la cible « CMakeFiles/pbcvt.dir/all » a échouée
make[1]: *** [CMakeFiles/pbcvt.dir/all] Erreur 2
Makefile:129 : la recette pour la cible « all » a échouée
make: *** [all] Erreur 2
What am I doing wrong? And how could I get the desired result?
The key indicator of the problem is this line in the compilation error:
/usr/include/boost/python/converter/arg_to_python.hpp:181:72: error: incomplete type ‘boost::python::converter::detail::cannot_convert_raw_PyObject<_object*>’ used in nested name specifier
cannot_convert_raw_PyObject<T*>::to_python_use_handle_instead();
What this is telling you is that you cannot directly convert a PyObject* to an object. You need to tell it how to handle the ownership of the PyObject*. This is done with the boost::python::handle type.
Thus, changing this line:
return boost::python::make_tuple(true, ret);
to:
boost::python::make_tuple(true, boost::python::handle<>(ret));
will resolve the error.

Fixed! A strange error in chat server using boost

I have to make a synchronous chat server using boost. I almost completed the server code, it may be still far away from what it should be, but I got very strange error that I couldn't find anything about in Internet. I really want to fix it before continuing but I don't know how. Here is the code:
#include<iostream>
#include<list>
#include<map>
#include<queue>
#include<vector>
#include<cstdlib>
#include<ctime>
#include<boost/thread.hpp>
#include<boost/bind.hpp>
#include<boost/asio.hpp>
#include<boost/asio/ip/tcp.hpp>
using namespace std;
using namespace boost::asio;
using namespace boost::asio::ip;
typedef boost::shared_ptr<tcp::socket> socket_ptr;
typedef boost::shared_ptr<string> string_ptr;
typedef boost::shared_ptr< list<socket_ptr> > clientList_ptr;
typedef boost::shared_ptr< list<string> > nameList_ptr;
const int THREADS = 1;
io_service service;
tcp::acceptor acceptor(service, tcp::endpoint(tcp::v4(), 30001));
boost::mutex mtx;
clientList_ptr clientList(new list<socket_ptr>);
nameList_ptr nameList(new list<string>);
boost::asio::streambuf buff;
time_t timer;
void error(const char *msg)
{
perror(msg);
exit(1);
}
bool clientSentExit(string_ptr message)
{
return message->find("exit") != string::npos;
}
void disconnectClient(socket_ptr clientSock, const boost::system::error_code& error)
{
boost::system::error_code ec = error;
auto position = find(clientList->begin(), clientList->end(), clientSock);
clientSock->shutdown(tcp::socket::shutdown_both, ec);
clientSock->close(ec);
clientList->erase(position);
cout << "Client Disconnected! " << clientList->size() << " total clients" << endl;
}
void do_processing(socket_ptr sock, const boost::system::error_code& error)
{
if(!clientList->empty())
{
mtx.lock();
boost::asio::streambuf buff;
size_t bytes_transferred = boost::asio::read_until(*sock, buff, '\n');
buff.commit(bytes_transferred);
std::istream istrm(&buff);
string_ptr msg(new string(""));
std::getline(istrm, *msg);
msg->push_back('\n');
buff.consume(buff.size());
if(clientSentExit(msg) || error)
{
disconnectClient(sock, error);
}
else
{
cout << "ChatLog: " << *msg << endl;
for(auto& cliSock : *clientList)
{
if (cliSock->is_open() && cliSock != sock)
{
cout << "Sending: " << time(&timer) << endl;
sock->write_some(buffer(*msg));
}
}
}
mtx.unlock();
}
}
int main(int argc, char *argv[])
{
boost::thread_group threads;
while (true)
{
cout << "Waiting for clients...\n";
socket_ptr clientSock(new tcp::socket(service));
acceptor.accept(*clientSock);
clientList->emplace_back(clientSock);
threads.create_thread(boost::bind(do_processing, clientSock, boost::asio::placeholders::error));
}
threads.join_all();
getc(stdin);
return 0;
}
And here is the error message:
In file included from /sapmnt/HOME/i322722/usr/boost/include/boost/bind.hpp:22:0,
from /sapmnt/HOME/i322722/usr/boost/include/boost/thread/detail/thread.hpp:30,
from /sapmnt/HOME/i322722/usr/boost/include/boost/thread/thread_only.hpp:22,
from /sapmnt/HOME/i322722/usr/boost/include/boost/thread/thread.hpp:12,
from /sapmnt/HOME/i322722/usr/boost/include/boost/thread.hpp:13,
from server.cpp:9:
/sapmnt/HOME/i322722/usr/boost/include/boost/bind/bind.hpp: In instantiation of \u2018void boost::_bi::list2<A1, A2>::operator()(boost::_bi::type<void>, F&, A&, int) [with F = void (*)(boost::shared_ptr<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >, const boost::system::error_code&); A = boost::_bi::list0; A1 = boost::_bi::value<boost::shared_ptr<boost::asio::basic_stream_socket<boost::asio::ip::tcp> > >; A2 = boost::arg<1> (*)()]\u2019:
/sapmnt/HOME/i322722/usr/boost/include/boost/bind/bind.hpp:895:50: required from \u2018boost::_bi::bind_t<R, F, L>::result_type boost::_bi::bind_t<R, F, L>::operator()() [with R = void; F = void (*)(boost::shared_ptr<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >, const boost::system::error_code&); L = boost::_bi::list2<boost::_bi::value<boost::shared_ptr<boost::asio::basic_stream_socket<boost::asio::ip::tcp> > >, boost::arg<1> (*)()>; boost::_bi::bind_t<R, F, L>::result_type = void]\u2019
/sapmnt/HOME/i322722/usr/boost/include/boost/thread/detail/thread.hpp:116:17: required from \u2018void boost::detail::thread_data<F>::run() [with F = boost::_bi::bind_t<void, void (*)(boost::shared_ptr<boost::asio::basic_stream_socket<boost::asio::ip::tcp> >, const boost::system::error_code&), boost::_bi::list2<boost::_bi::value<boost::shared_ptr<boost::asio::basic_stream_socket<boost::asio::ip::tcp> > >, boost::arg<1> (*)()> >]\u2019
**server.cpp:218:1: required from here
/sapmnt/HOME/i322722/usr/boost/include/boost/bind/bind.hpp:315:56: error: no match for \u2018operator[]\u2019 (operand types are \u2018boost::_bi::list0\u2019 and \u2018boost::arg<1>()\u2019)
unwrapper<F>::unwrap(f, 0)(a[base_type::a1_], a[base_type::a2_]);**
The numbers in the "required from here" statements are wrong because I have many comments which I want to keep in the IDE, but deleted here. The actual line in which the error occurs is the very last line of the code - with the '}' that closes the main function.
I would be grateful for any answers.
It's fixed now. As they told me, it's something like a confrontation between
const boost::system::error_code& error
and
boost::asio::placeholders::error.
They told me that these error codes are not needed, they are required if the chat server is asynchronous, but here the thread group cannot send an error code.
I'm not sure if I have understood perfectly everything and sorry if the answer seems badly written. Removing the error codes everywhere except for:
boost::system::error_code ec;
fixed the problem.

overloading new and delete in c++

HI All,
I was trying to overload new and delete to fix a memory leak problem in my project. But got stuck with some compilation error.
Currently this code is bit shabby
Here is my hdr file
#include <cstddef>
#include <iostream>
#include <list>
#include <stdarg.h>
#include <stdio.h>
using namespace std;
typedef unsigned int DWORD;
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum);
char *OutputDebugString (const char *fmt, ...);
void RemoveTrack(DWORD addr);
void DumpUnfreed();
#ifdef _DEBUG
#define DEBUG_NEW new(__FILE__, __LINE__)
#define new DEBUG_NEW
void * operator new (unsigned int size, const char *file, int line)
{
void *ptr = (void *)malloc(size);
AddTrack((DWORD)ptr, size, file, line);
return(ptr);
}
/*inline void * operator new(unsigned int size)
{
void *ptr = (void *)malloc(size);
AddTrack((DWORD)ptr, size, _FILE_,_LINE_);
return(ptr);
}*/
void operator delete(void *p)
{
RemoveTrack((DWORD)p);
free(p);
}
#endif
char *OutputDebugString (const char *fmt, ...)
{
char *p = NULL;
size_t size = 1024;
int n = 0;
va_list ap;
if((p = (char*) malloc(size)) == NULL)
return NULL;
while(1) {
va_start(ap, fmt);
n = vsnprintf(p, size, fmt, ap);
va_end(ap);
if(n > -1 && n < size)
return p;
/* failed: have to try again, alloc more mem. */
if(n > -1) /* glibc 2.1 */
size = n + 1;
else /* glibc 2.0 */
size *= 2; /* twice the old size */
if((p = (char *)realloc (p, size)) == NULL)
return NULL;
}
}
typedef struct information {
DWORD address;
DWORD size;
char file[64];
DWORD line;
} ALLOC_INFO;
typedef list < ALLOC_INFO* > AllocList;
AllocList *allocList;
void AddTrack(DWORD addr, DWORD asize, const char *fname, DWORD lnum)
{
ALLOC_INFO *info;
if(!allocList) {
//allocList = new AllocList;
allocList = (AllocList*)malloc (sizeof (AllocList));
}
//info = new(ALLOC_INFO);
info = (ALLOC_INFO*) malloc (sizeof (ALLOC_INFO));
info->address = addr;
strncpy(info->file, fname, 63);
info->line = lnum;
info->size = asize;
allocList->insert(allocList->begin(), info);
}
void RemoveTrack(DWORD addr)
{
AllocList::iterator i;
if(!allocList)
if(!allocList)
return;
for(i = allocList->begin(); i != allocList->end(); i++)
{
if((*i)->address == addr)
{
allocList->remove((*i));
break;
}
}
}
void DumpUnfreed()
{
AllocList::iterator i;
DWORD totalSize = 0;
char buf[1024];
if(!allocList)
return;
for(i = allocList->begin(); i != allocList->end(); i++) {
sprintf(buf, "%-50s:\t\tLINE %d,\t\tADDRESS %d\t%d unfreed\n",
(*i)->file, (*i)->line, (*i)->address, (*i)->size);
OutputDebugString("%s",buf);
totalSize += (*i)->size;
}
sprintf(buf, "-----------------------------------------------------------\n");
OutputDebugString("%s",buf);
sprintf(buf, "Total Unfreed: %d bytes\n", totalSize);
OutputDebugString("%s",buf);
}
And my main.cpp is
#include "mynew.h"
int main()
{
char *ptr = new char;
DumpUnfreed();
return 0;
}
When i try to compile i get the following error
[root#dhcppc0 new]# !g
g++ main.cpp -D_DEBUG
mynew.h:25: error: declaration of ‘operator new’ as non-function
main.cpp: In function ‘int main()’:
main.cpp:9: error: no matching function for call to ‘operator new(unsigned int, const char [9], int)’
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:84: note: candidates are: void* operator new(size_t)
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:88: note: void* operator new(size_t, const std::nothrow_t&)
/usr/lib/gcc/i386-redhat-linux/4.1.1/../../../../include/c++/4.1.1/new:94: note: void* operator new(size_t, void*)
I know there is some thing wrong with my #defines, but I am not sure what is wrong.
Can any one please bale me out of this
You've defined your new macro before your functions. Your code ends up looking like:
void *
operator new(__FILE__, __LINE__)(unsigned int size, const char *file, int line)
Which is obviously wrong. Your should move the macro definitions underneath the functions (or better is to keep those functions in a .cpp file you link with.) For what it's worth, new is a keyword and cannot be an identifier, so your program is, strictly speaking, ill-formed.
I recently posted my global memory operators framework. It might help you a bit.
the signature don't match it sould be void* operator new (size_t size).
overriding single object new signature is
static void * operator new(site_t size),
roni