473,769 Members | 6,653 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Strange template behaviour with strings

29 New Member
I have written a Queue class for our use that stores pointers to what I call RequestObjects. RequestObjects are a base class from which other types inherit and this allows the queue (or deque in this case) to hold values of different types. When popping values off the deque, the values are then typecasted back to their useful derived type. So far the class has worked well except with strings. When string values are typecasted back to be read off the deque the program segfaults. Here's a quick example of the code and the result of the unit test at the bottom:

Expand|Select|Wrap|Line Numbers
  1. // Queue.h
  2.    class RequestObject
  3.    {
  4.      public:
  5.       // Constructor
  6.       RequestObject(){ mType = -1; }
  7.       virtual ~RequestObject(){}
  8.  
  9.       int GetType() const { return mType; }
  10.       void SetType(int i) { mType = i; }
  11.  
  12.      private:
  13.       int mType;
  14.    };
  15.  
  16.    template <class T>
  17.    class SingleValueReq : public RequestObject
  18.    {
  19.       public:
  20.          SingleValueReq(){ mValue = NULL; }
  21.          SingleValueReq(T b){ mValue = new T(b); }
  22.          virtual ~SingleValueReq(){ delete mValue; }
  23.  
  24.          void SetValue(T value){ delete mValue; mValue = new T(value); }
  25.          T GetValue(){ return(*mValue); }
  26.       private:
  27.          T    *mValue;
  28.    };
  29.  
  30.    class QueueObject
  31.    {
  32.    public:
  33.        QueueObject(){}
  34.        ~QueueObject(){}
  35.  
  36.        // Public Methods
  37.        bool Empty();
  38.        RequestObject *Pop();
  39.        void Clear();
  40.  
  41.       // Add mechanism
  42.        template <typename T>
  43.        void Add(int type, T value)
  44.        {
  45.           SingleValueReq<T> *O = new SingleValueReq<T>(value);
  46.           O->SetType(type);
  47.           Q.push_back(O);
  48.           // debug code
  49.           O = (SingleValueReq<T> *)Q.back();
  50.           std::cout << "Add " << O->GetValue() << std::endl;
  51.        }
  52.  
  53.    private:
  54.        std::deque<RequestObject *> Q;
  55.    };
  56.  
  57. // From file Queue.cpp
  58. RequestObject *QueueObject::Pop()
  59. {
  60.     RequestObject *O = Q.front();
  61.     Q.pop_front();
  62.     return(O);
  63. }
  64.  
  65. bool QueueObject::Empty()
  66. {
  67.    return(Q.empty());
  68. }
  69.  
  70. // From test program QueueTest.cpp
  71. int main(int argc, char *argv[])
  72. {
  73.    QueueObject mQ;
  74.  
  75.    mQ.Add(10, -1.0);
  76.    mQ.Add(11, true);
  77.    mQ.Add(12, -1);
  78.    mQ.Add(13, false);
  79.    mQ.Add(14, "StringTest!!!");
  80.  
  81.    while(!mQ.Empty())
  82.    {
  83.       RequestObject *O = mQ.Pop();
  84.  
  85.          switch(O->GetType())
  86.          {
  87.             case(10):
  88.                {
  89.                   SingleValueReq<double> *ip = (SingleValueReq<double> *)(O);
  90.                   cout << "Value = " << ip->GetValue();
  91.                }
  92.                break;
  93.             case(11):
  94.                {
  95.                   SingleValueReq<bool> *ip = static_cast<SingleValueReq<bool> *> (O);
  96.                   cout << "Value = " << ip->GetValue();
  97.                }
  98.                break;
  99.             case(12):
  100.                {
  101.                   SingleValueReq<int> *ip = static_cast<SingleValueReq<int> *> (O);
  102.                   cout << "Value = " << ip->GetValue();
  103.                }
  104.                break;
  105.             case(13):
  106.                {
  107.                   SingleValueReq<bool> *ip = static_cast<SingleValueReq<bool> *> (O);
  108.                   cout << "Value = " << ip->GetValue();
  109.                }
  110.                break;
  111.             case(14):
  112.                {
  113.                   SingleValueReq<string> *ip = (SingleValueReq<string> *) (O);
  114.                   cout << "Value = " << ip->GetValue();
  115.                }
  116.                break;
  117.             default:
  118.                break;
  119.          }
  120.       cout << endl;
  121.    }
  122.  
  123.    return(0);
  124. }
  125.  
  126. // Sample output from QueueTest.cpp
  127. ]./QueueTest
  128. Add -1
  129. Add 1
  130. Add -1
  131. Add 0
  132. Add StringTest!!!
  133. Value = -1
  134. Value = 1
  135. Value = -1
  136. Value = 0
  137. Segmentation fault
  138.  
  139.  
I've debugged this as far as my understanding can take me but cannot figure out why the string becomes corrupted but the other values don't. Any help or ideas?

Thanks!

-Marco
Dec 10 '08 #1
5 1740
weaknessforcats
9,208 Recognized Expert Moderator Expert
Typecasting in C++ means a) you are calling a relic C function with some soirt of void* argument or b) your C++ design is faulty.

In this case, the design is faulty.

I suggest you use the Visitor design pattern.
Dec 10 '08 #2
meLlamanJefe
29 New Member
I appreciate you pointing out that the design is faulty and I will take a look at the visitor design pattern as you suggest. However, being new at this your answer does not really mention which part is faulty and why. Could you explain that?

Thanks.
Dec 10 '08 #3
weaknessforcats
9,208 Recognized Expert Moderator Expert
It's because of the typecast.

Whenever you have to tell a C++ compiler what the type is, there is something fishy. Plus ion order to write the typecast in the firslt place you need to know the type you are casting to. That means hard-coded types in your programs and that means the program may need to be altered as new derived classes are added. If there are a lot of copies of this code in use, then a lot of changes will be required to add you new derved type.

However, I compiled your code and ran it with no seg fault using Visual Studio.NET 2008.
Dec 10 '08 #4
meLlamanJefe
29 New Member
Got it. I completely understand the limitation with respect to the hard coding of the code. I hop to understand the visitor pattern and implement it if that can make our code more flexible. I'm glad but confused to hear that the code worked for you. While it is not the cleanest code I did not see anything in it that told me it would not work which is why we were using this design. We are running in Linux and are building our code using gcc 4.1.2 so I'm guessing it is a problem with the compiler. Oh well...

Thanks for your help!
Dec 10 '08 #5
meLlamanJefe
29 New Member
Just a quick update as reference for others that may look at this post. I finally understood the reason why the code above segfaults and it was not due to a bug in gcc.

The problem is in line 79. A quoted string passed to a method in C++ is not passed as a std::string but as a const char *. In newer languages like C# or Java I think the quoted text in line 79 would have been treated as a string object. So the first problem was in line 113 where the object returning from the Queue was templated into a string while in fact being a const char array. Finally in line 114 when the GetValue method tried to access the value in the SingleValueReq object the program crashed. The other problem is that passing a const char array is extremely unsafe because there is no information on the length of the array and thus the GetValue method could easily overrun the array's limits and return garbage.

The easy fix was to create a string object with the char array value and then add it to the Queue. The rest of the code then works properly.

The CORRECT fix is to read up on the visitor pattern and re-implement the request objects in that way. (I'm still working on that but hope to get it working soon).

thanks!
Dec 11 '08 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

4
5613
by: Ben | last post by:
Hi all, I'm trying to figure out how how complex map, filter and reduce work based on the following piece of code from http://www-106.ibm.com/developerworks/linux/library/l-prog.html : bigmuls = lambda xs,ys: filter(lambda (x,y):x*y > 25, combine(xs,ys)) combine = lambda xs,ys: map(None, xs*len(ys), dupelms(ys,len(xs))) dupelms = lambda lst,n: reduce(lambda s,t:s+t, map(lambda l,n=n: *n, lst))
9
2491
by: muser | last post by:
I have written a function that checks the first four characters in an address are valid; i.e. 1d2 sour st would prove to be invalid. bool checkdigitsinaddress( const char* string ) { for( int i =0; i<=1; i++ ) if( !isdigit( string )){} return false; for(i=1; i<=2; i++)
2
3075
by: Alex Mizrahi | last post by:
Hello, All! i admit that it's better to ask questions connected with atl/mfc classes in special newsgroups, but seems like people there are interested more in discussing stuff like MFC GUI than C++ 8-/, so i'll better ask here too.. CStringW is a class in atl/mfc dealing with strings 8-]. the only typecast operator i found is to PCXSTR that is LPCWSTR that is simply "const unsigned short*" (wchar_t is unsigned short). wcout accepts...
14
2905
by: Bart Samwel | last post by:
Hi everybody, I would really like some help explaining this apparent discrepancy, because I really don't get it. Here is the snippet: void foo(int&); void foo(int const&); template<typename T>
5
2314
by: catch | last post by:
Hi, Suppose I have a table something like: name (VARCHAR(64)) age (INT) quotation (TEXT) ================================================= Donald Trump 50 I am rich Bugs Bunny 26 What's up doc ...
5
1693
by: sleepydj | last post by:
Hello, I have a simple program to create strings from the corresponding double/integer values. For any data type similar to int, I have a template set up in a file misc.h: ************************************************************************************* //misc.h #ifndef __MISC_H__ #define __MISC_H__
6
2935
by: Edd Dawson | last post by:
Hi. I have a strange problem involving the passing of command line arguments to a C program I'm writing. I tried posting this in comp.programming yesterday but someone kindly suggested that I'd have better luck here. So here goes! My program ignores any command line arguments, or at least it's supposed to. However, when I pass any command line arguments to the program, the behaviour of one of the functions changes mysteriously. I have...
1
3342
by: Shukri Adams | last post by:
I'm getting a weird error with IndexOf. It only occurs if the substring length is 1. "aaa".IndexOf("a") for example should return 0 , ie, it should find the first "a" in "aaa". Instead, it return 2, the last "a". This error does not occur in "aaaa".IndexOf("aa")
3
1696
by: gorbulastic | last post by:
ok, i've created a typedef of somthing, and I put it through a for loop to put the entries into it. They are stored as an array of the typedef''s, with memory allocated via malloc command. For some strange reason, one of the strings that make up the typedef, ends up being exactly the same in every typdef in the array (and it shouldn't). Ive been debugging and using printf's to view the before and after values of this particular string,...
0
9589
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
10216
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
0
10049
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven tapestry of website design and digital marketing. It's not merely about having a website; it's about crafting an immersive digital experience that captivates audiences and drives business growth. The Art of Business Website Design Your website is...
1
9997
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
9865
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6675
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5309
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
2
3565
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2815
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.