Invalid Pointer Addition
by Curtis Krauskopf
The following program is the 'guts' of a string class
written for an older version of C++. It compiles
without problems on a Borland 4.52 C++ compiler, but
it compiles with an Invalid Pointer Addition
error in BCBuilder 4.0.
#include <condefs.h>
#include <iostream.h>
#include <string.h>
#include <stdio.h> // for printf()
class String {
char *sptr;
int length;
void putstr(char *s);
public:
// -------- construct a null string
String() { sptr = NULL; }
// --- construct with char * initializer
String(char *s);
// ------- copy constructor
String(String& s);
// -------- construct with a size and fill character
String(int len, char fill = 0);
// ------- destructor
~String() { delete sptr; }
// ---------- conversion to char *
operator char *() { return sptr; }
// --- concatenation operator (str1 + str2;)
String operator+(String &s);
};
// ------- put a string into a String
void String::putstr(char *s)
{
delete sptr;
length = 0;
sptr = 0;
if (s) {
length = strlen(s);
sptr = new char[length+1];
strcpy(sptr, s);
}
}
// --- convert from char *
String::String(char *s) {
sptr = NULL;
putstr(s);
}
// ------- copy constructor
String::String(String& s) {
sptr = NULL;
putstr(s.sptr);
}
// -------- construct with a size and fill character
String::String(int len, char fill) {
length = len;
sptr = new char[length+1];
memset(sptr, fill, length);
*(sptr+len) = '\0';
}
// ------- concatenation operator (str1 + str2)
String String::operator+(String &s) {
String temp(strlen(s.sptr) + strlen(sptr));
strcpy(temp.sptr, sptr);
strcat(temp.sptr, s.sptr);
return temp;
}
#pragma argsused
int main(int argc, char* argv[])
{
String x;
String y("Hello");
// [C++ Error] main.cpp(83): E2085 Invalid pointer addition.
x = y + String("World");
return 0;
}
Analysis:
The line:
x =
y + String("World");
is not the cause of the problem because it's obvious
that both x and y are String objects.
So why is the compiler trying to add the pointers of
these objects?
Clue: see if automatic conversion is causing
a problem. Try removing the
operator
char *() {
return sptr; }
definition from the class.
Result of removing operator char *():
We now get a different compile-time error on the same
line:
[C++ Error] main1.cpp(83): E2093
'operator+' not implemented in type 'String' for arguments
of the same type.
Well, operator+ is obviously
defined in the String class. But is it
defined correctly?
Solution:
No, it's not defined correctly.
operator+ should be defined as:
String operator+(const String &s)
const;
Because the compiler could not find an
operator+ that takes a const String argument,
it tried to apply one of the default conversion operators
to the expression. In this case, operator char
* fit the bill nicely and was used by the compiler.
However, this caused an illegal pointer addition and
so that is what the compiler reported.
Here is the above sample code
with the corrections included. The changes have
been highlighted in red.
#include <condefs.h>
#include <iostream.h>
#include <string.h>
#include <stdio.h> // for printf()
class String {
char *sptr;
int length;
void putstr(char *s);
public:
// -------- construct a null string
String() { sptr = NULL; }
// --- construct with char * initializer
String(char *s);
// ------- copy constructor
String(String& s);
// -------- construct with a size
and fill character
String(int len, char fill = 0);
// ------- destructor
~String() { delete sptr; }
// ---------- conversion to char
*
operator char *() { return sptr;
}
// --- concatenation operator (str1
+ str2;)
String operator+(const
String &s) const;
};
// ------- put a string into a String
void String::putstr(char *s)
{
delete sptr;
length = 0;
sptr = 0;
if (s) {
length =
strlen(s);
sptr = new
char[length+1];
strcpy(sptr,
s);
}
}
// --- convert from char *
String::String(char *s) {
sptr = NULL;
putstr(s);
}
// ------- copy constructor
String::String(String& s) {
sptr = NULL;
putstr(s.sptr);
}
// -------- construct with a size and fill character
String::String(int len, char fill) {
length = len;
sptr = new char[length+1];
memset(sptr, fill, length);
*(sptr+len) = '\0';
}
// ------- concatenation operator (str1 + str2)
String String::operator+(const
String &s) const
{
String temp(strlen(s.sptr) + strlen(sptr));
strcpy(temp.sptr, sptr);
strcat(temp.sptr, s.sptr);
return temp;
}
#pragma argsused
int main(int argc, char* argv[])
{
String x;
String y("Hello");
// compiles okay now
x = y + String("World");
return 0;
}
Popular C++ topics at The Database Managers:
|