thinking in c++ vol 2 question

Started by
8 comments, last by JasonL220 17 years, 10 months ago
in the section on memory leak detection it says that the code does not following the standard why is that?
Advertisement
Could you be more specific? What code does it say is non-standard?
1. Even though it’s technically illegal, it works on many compilers.

//: C02:MemCheck.h
#ifndef MEMCHECK_H
#define MEMCHECK_H
#include <cstddef> // For size_t

// Usurp the new operator (both scalar and array versions)
void* operator new(std::size_t, const char*, long);
void* operator new[](std::size_t, const char*, long);
#define new new (__FILE__, __LINE__)

extern bool traceFlag;
#define TRACE_ON() traceFlag = true
#define TRACE_OFF() traceFlag = false

extern bool activeFlag;
#define MEM_ON() activeFlag = true
#define MEM_OFF() activeFlag = false

#endif // MEMCHECK_H ///:~


//: C02:MemCheck.cpp {O}
#include <cstdio>
#include <cstdlib>
#include <cassert>
#include <cstddef>
using namespace std;
#undef new

// Global flags set by macros in MemCheck.h
bool traceFlag = true;
bool activeFlag = false;

namespace {

// Memory map entry type
struct Info {
void* ptr;
const char* file;
long line;
};

// Memory map data
const size_t MAXPTRS = 10000u;
Info memMap[MAXPTRS];
size_t nptrs = 0;

// Searches the map for an address
int findPtr(void* p) {
for(size_t i = 0; i < nptrs; ++i)
if(memMap.ptr == p)
return i;
return -1;
}

void delPtr(void* p) {
int pos = findPtr(p);
assert(pos >= 0);
// Remove pointer from map
for(size_t i = pos; i < nptrs-1; ++i)
memMap = memMap[i+1];
--nptrs;
}

// Dummy type for static destructor
struct Sentinel {
~Sentinel() {
if(nptrs > 0) {
printf("Leaked memory at:\n");
for(size_t i = 0; i < nptrs; ++i)
printf("\t%p (file: %s, line %ld)\n",
memMap.ptr, memMap.file, memMap.line);
}
else
printf("No user memory leaks!\n");
}
};

// Static dummy object
Sentinel s;

} // End anonymous namespace

// Overload scalar new
void*
operator new(size_t siz, const char* file, long line) {
void* p = malloc(siz);
if(activeFlag) {
if(nptrs == MAXPTRS) {
printf("memory map too small (increase MAXPTRS)\n");
exit(1);
}
memMap[nptrs].ptr = p;
memMap[nptrs].file = file;
memMap[nptrs].line = line;
++nptrs;
}
if(traceFlag) {
printf("Allocated %u bytes at address %p ", siz, p);
printf("(file: %s, line: %ld)\n", file, line);
}
return p;
}

// Overload array new
void*
operator new[](size_t siz, const char* file, long line) {
return operator new(siz, file, line);
}

// Override scalar delete
void operator delete(void* p) {
if(findPtr(p) >= 0) {
free(p);
assert(nptrs > 0);
delPtr(p);
if(traceFlag)
printf("Deleted memory at address %p\n", p);
}
else if(!p && activeFlag)
printf("Attempt to delete unknown pointer: %p\n", p);
}

// Override array delete
void operator delete[](void* p) {
operator delete(p);
} ///:~


on about page 95
I believe the line:
#define new new (__FILE__, __LINE__)
is illegal. I'm pretty sure that #defining a keyword isn't allowed.
The most obvious thing is the implementation of operator new, most notably:

// Overload scalar newvoid*operator new(size_t siz, const char* file, long line) {void* p = malloc(siz);if(activeFlag) {if(nptrs == MAXPTRS) {printf("memory map too small (increase MAXPTRS)\n");exit(1);}memMap[nptrs].ptr = p;memMap[nptrs].file = file;memMap[nptrs].line = line;++nptrs;}if(traceFlag) {printf("Allocated %u bytes at address %p ", siz, p);printf("(file: %s, line: %ld)\n", file, line);}return p;}


1) It doesn't handle the size == 0 case
2) It doesn't call the new-handler if insufficient memory is available
3) It doesn't contain a loop around the allocation
4) It doesn't throw std::bad_alloc if it can't satisfy the request
is there another way of replacing new without #define new?
AFAIK #define new is perfectly legal
ASCII stupid question, get a stupid ANSI
@jasonL220: Yes, one can overload the operator.

@Yohumbus: You're right. Anything that would syntaxically be eligible to be an identifier can be #defined (regardless of the fact they are keywords or not, since preprocessing occurs, as the name says, before compiling.

Valid:
#define new delete // very powerful ;)
#define true false
etc.

Invalid:
#define 0 1

http://www-ccs.ucsd.edu/c/preproc.html#Preprocessing%20Tokens
so what makes that code illegal?

This topic is closed to new replies.

Advertisement