|
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; } Back to CPP FAQ |