Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > C++ > Strings with Templates not working?

Reply
Thread Tools

Strings with Templates not working?

 
 
Obnoxious User
Guest
Posts: n/a
 
      06-20-2007
On Wed, 20 Jun 2007 21:41:13 +0200, Markus Pitha wrote:

> Hello,
>
> I'm using a template to simulate a LinkedList from Java.It works without
> problems, but when I want to use strings in main.cpp instead of char*, I
> get the following error message:
>
> $ ./Main
> terminate called after throwing an instance of 'std::logic_error'
> what(): basic_string::_S_construct NULL not valid
>
> I tried to import <string> both in main.cpp and listT.h, but the
> errormsg was the same.
>
> The classes look like this:
>

[snip]
> template <class T>
> T ListT<T>::get(int i) {
> TKnoten *iterator = new TKnoten();
> T daten = 0;

!---->>^^^^^^^^^^^

T daten = "";


> iterator = kopf;
> while (iterator->next != 0) {
> if (iterator->index == i) {
> daten = iterator->daten;
> }
> iterator = iterator->next;
> }
> delete iterator;
> return daten;
> }
>
> What's wrong with string as type? I'm using Linux with gcc (g++),


--
Obnoxious User
 
Reply With Quote
 
 
 
 
Markus Pitha
Guest
Posts: n/a
 
      06-20-2007
Hello,

I'm using a template to simulate a LinkedList from Java.It works without
problems, but when I want to use strings in main.cpp instead of char*, I
get the following error message:

$ ./Main
terminate called after throwing an instance of 'std::logic_error'
what(): basic_string::_S_construct NULL not valid

I tried to import <string> both in main.cpp and listT.h, but the
errormsg was the same.

The classes look like this:

MAIN.CPP------------------------------------------
#include "ListT.h"
#include <iostream>

using namespace std;

int main(void) {

ListT<string> *testList = new ListT<string>();
testList->add("Test1");
testList->add("Test2");
testList->add("Test3");
cout << testList->get(0) <<endl;
cout << testList->get(1) <<endl;
cout << testList->get(2) <<endl;
delete testList;

return 0;
}
------------------------------------------------

LISTT.H-----------------------------------------

template <class T> class ListT {

private:
struct TKnoten {
T daten;
int index;
TKnoten *next;
};
int counter;
TKnoten *kopf;

public:
ListT();
virtual ~ListT();
void add(T element);
//void remove(T element);
T get(int i);
};

template <class T>
ListT<T>::ListT() {
counter = 0;
kopf = new TKnoten();
kopf->next = 0;
}

template <class T>
ListT<T>::~ListT() {
while (kopf->next != 0) {
TKnoten *previous = new TKnoten();
previous = kopf;
kopf = kopf->next;
delete previous;
}
delete kopf;
}

template <class T>
void ListT<T>::add(T element) {
TKnoten *newKnoten = new TKnoten();

newKnoten->next = kopf;
kopf = newKnoten;
kopf->daten = element;
kopf->index = counter;
counter++;
}

template <class T>
T ListT<T>::get(int i) {
TKnoten *iterator = new TKnoten();
T daten = 0;
iterator = kopf;
while (iterator->next != 0) {
if (iterator->index == i) {
daten = iterator->daten;
}
iterator = iterator->next;
}
delete iterator;
return daten;
}

What's wrong with string as type? I'm using Linux with gcc (g++),


Thanks for your answers,

Markus
 
Reply With Quote
 
 
 
 
Obnoxious User
Guest
Posts: n/a
 
      06-20-2007
On Wed, 20 Jun 2007 19:37:49 +0000, Obnoxious User wrote:

> On Wed, 20 Jun 2007 21:41:13 +0200, Markus Pitha wrote:
>
>> Hello,
>>
>> I'm using a template to simulate a LinkedList from Java.It works without
>> problems, but when I want to use strings in main.cpp instead of char*, I
>> get the following error message:
>>
>> $ ./Main
>> terminate called after throwing an instance of 'std::logic_error'
>> what(): basic_string::_S_construct NULL not valid
>>
>> I tried to import <string> both in main.cpp and listT.h, but the
>> errormsg was the same.
>>
>> The classes look like this:
>>

> [snip]
>> template <class T>
>> T ListT<T>::get(int i) {
>> TKnoten *iterator = new TKnoten();
>> T daten = 0;

> !---->>^^^^^^^^^^^
>
> T daten = "";
>


Or better yet, so it works with any type.

T daten;

>
>> iterator = kopf;
>> while (iterator->next != 0) {
>> if (iterator->index == i) {
>> daten = iterator->daten;
>> }
>> iterator = iterator->next;
>> }
>> delete iterator;
>> return daten;
>> }
>>
>> What's wrong with string as type? I'm using Linux with gcc (g++),

>


--
Obnoxious User
 
Reply With Quote
 
Zachary Turner
Guest
Posts: n/a
 
      06-20-2007
On Jun 20, 2:41 pm, Markus Pitha <(E-Mail Removed)> wrote:
> template <class T>
> T ListT<T>::get(int i) {
> TKnoten *iterator = new TKnoten();
> T daten = 0;


Pretty sure this is your problem. You're assigning NULL to a string
object.

I know this isn't your question, but you know that C++ already comes
with a linked list right? And also, it may have been better style to
declare your list on the stack instead of as a pointer and then using
new / delete. You may be aware of this already, but from your post it
sounds like you come from a Java background, where everything is just
new new new allocated on the heap.

 
Reply With Quote
 
Victor Bazarov
Guest
Posts: n/a
 
      06-20-2007
Markus Pitha wrote:
> Hello,
>
> I'm using a template to simulate a LinkedList from Java.It works
> without problems, but when I want to use strings in main.cpp instead
> of char*, I get the following error message:
>
> $ ./Main
> terminate called after throwing an instance of 'std::logic_error'
> what(): basic_string::_S_construct NULL not valid
>
> I tried to import <string> both in main.cpp and listT.h, but the
> errormsg was the same.


You have some logical errors in your code. See below.

>
> The classes look like this:
>
> MAIN.CPP------------------------------------------
> #include "ListT.h"
> #include <iostream>
>
> using namespace std;
>
> int main(void) {
>
> ListT<string> *testList = new ListT<string>();
> testList->add("Test1");
> testList->add("Test2");
> testList->add("Test3");
> cout << testList->get(0) <<endl;
> cout << testList->get(1) <<endl;
> cout << testList->get(2) <<endl;
> delete testList;
>
> return 0;
> }
> ------------------------------------------------
>
> LISTT.H-----------------------------------------
>
> template <class T> class ListT {
>
> private:
> struct TKnoten {
> T daten;
> int index;
> TKnoten *next;


The 'TKnoten' struct is not a POD, which means that upon its
default-initialisation both 'index' and 'next' contain garbage.
You should write a default c-tor which will initialise 'index'
to something specific, like -1, and 'next' to NULL.

> };
> int counter;
> TKnoten *kopf;
>
> public:
> ListT();
> virtual ~ListT();
> void add(T element);
> //void remove(T element);
> T get(int i);
> };
>
> template <class T>
> ListT<T>::ListT() {
> counter = 0;
> kopf = new TKnoten();
> kopf->next = 0;
> }
>
> template <class T>
> ListT<T>::~ListT() {
> while (kopf->next != 0) {
> TKnoten *previous = new TKnoten();
> previous = kopf;


Take a close look at the previous two statements. You create
a new 'TKnoten' object, obtain a pointer to it and IMMEDIATELY
lose it by overriding the value in 'previous'. Do you really
need to create a new 'TKnoten' here while deleting your list?

> kopf = kopf->next;
> delete previous;
> }
> delete kopf;
> }
>
> template <class T>
> void ListT<T>::add(T element) {
> TKnoten *newKnoten = new TKnoten();
>
> newKnoten->next = kopf;
> kopf = newKnoten;
> kopf->daten = element;
> kopf->index = counter;
> counter++;
> }
>
> template <class T>
> T ListT<T>::get(int i) {
> TKnoten *iterator = new TKnoten();


HUH? Why are you creating another 'TKnoten' here?

> T daten = 0;
> iterator = kopf;


Again, you're immediately losing the value of 'iterator' that you
just obtained from 'new'...

> while (iterator->next != 0) {
> if (iterator->index == i) {
> daten = iterator->daten;
> }
> iterator = iterator->next;
> }
> delete iterator;


Are you sure you need to 'delete' it here?

> return daten;
> }
>
> What's wrong with string as type? I'm using Linux with gcc (g++),


Nothing is wrong with string as type. Several things are wrong with
your program, however. The main thing I'd look closely into would
be the 'delete iterator' in the 'get' member function.

V
--
Please remove capital 'A's when replying by e-mail
I do not respond to top-posted replies, please don't ask


 
Reply With Quote
 
Markus Pitha
Guest
Posts: n/a
 
      06-20-2007
Hello,

Obnoxious User wrote:
>> T daten = 0;

> !---->>^^^^^^^^^^^


Ah, I see. That's it.
By the way, why do I have to include <string> for using NULL?
At first, I thought I have to define NULL like this #define NULL (void*)
0 but I got some error about redefining null.
By coincidence, I found out that NULL is in string.

Markus


 
Reply With Quote
 
Obnoxious User
Guest
Posts: n/a
 
      06-20-2007
On Wed, 20 Jun 2007 22:19:16 +0200, Markus Pitha wrote:

> Zachary Turner wrote:
>> I know this isn't your question, but you know that C++ already comes
>> with a linked list right? And also, it may have been better style to
>> declare your list on the stack instead of as a pointer and then using
>> new / delete.

>
> Where can I find this linked list? In the internet, I only find
> tutorials how to create a linked list.


#include <list>
#include <iostream>


int main() {
std::list<int> list;
list.push_back(0);
list.push_back(1);
list.push_back(2);

std::cout<<"front: "<<list.front()<<std::endl;
std::cout<<"back: "<<list.back()<<std::endl;
std::cout<<"complete: ";
std::list<int>::iterator ii = list.begin();
while(true) {
std::cout<<*ii;
if(++ii == list.end()) break;
std::cout<<",";
}
std::endl(std::cout);
return 0;
}

--
Obnoxious User
 
Reply With Quote
 
Markus Pitha
Guest
Posts: n/a
 
      06-20-2007
Zachary Turner wrote:
> I know this isn't your question, but you know that C++ already comes
> with a linked list right? And also, it may have been better style to
> declare your list on the stack instead of as a pointer and then using
> new / delete.


Where can I find this linked list? In the internet, I only find
tutorials how to create a linked list.
Which benefits does it have to create it on the stack?
I thought that dynamically allocated space would be better.




 
Reply With Quote
 
Markus Pitha
Guest
Posts: n/a
 
      06-20-2007
Victor Bazarov schrieb:
> Markus Pitha wrote:
>> Hello,
>>
>> I'm using a template to simulate a LinkedList from Java.It works
>> without problems, but when I want to use strings in main.cpp instead
>> of char*, I get the following error message:
>>
>> $ ./Main
>> terminate called after throwing an instance of 'std::logic_error'
>> what(): basic_string::_S_construct NULL not valid
>>
>> I tried to import <string> both in main.cpp and listT.h, but the
>> errormsg was the same.

>
> You have some logical errors in your code. See below.
>
>> The classes look like this:
>>
>> MAIN.CPP------------------------------------------
>> #include "ListT.h"
>> #include <iostream>
>>
>> using namespace std;
>>
>> int main(void) {
>>
>> ListT<string> *testList = new ListT<string>();
>> testList->add("Test1");
>> testList->add("Test2");
>> testList->add("Test3");
>> cout << testList->get(0) <<endl;
>> cout << testList->get(1) <<endl;
>> cout << testList->get(2) <<endl;
>> delete testList;
>>
>> return 0;
>> }
>> ------------------------------------------------
>>
>> LISTT.H-----------------------------------------
>>
>> template <class T> class ListT {
>>
>> private:
>> struct TKnoten {
>> T daten;
>> int index;
>> TKnoten *next;

>
> The 'TKnoten' struct is not a POD, which means that upon its
> default-initialisation both 'index' and 'next' contain garbage.
> You should write a default c-tor which will initialise 'index'
> to something specific, like -1, and 'next' to NULL.


Ok.
> Take a close look at the previous two statements. You create
> a new 'TKnoten' object, obtain a pointer to it and IMMEDIATELY
> lose it by overriding the value in 'previous'. Do you really
> need to create a new 'TKnoten' here while deleting your list?


I have an old C book. They write the following in this book:

free(head);
head = head->next;

I thought this can not work, because how can I free the "head" of the
list _at first_ without losing the whole list?
>
>> kopf = kopf->next;
>> delete previous;
>> }
>> delete kopf;
>> }
>>
>> template <class T>
>> void ListT<T>::add(T element) {
>> TKnoten *newKnoten = new TKnoten();
>>
>> newKnoten->next = kopf;
>> kopf = newKnoten;
>> kopf->daten = element;
>> kopf->index = counter;
>> counter++;
>> }
>>
>> template <class T>
>> T ListT<T>::get(int i) {
>> TKnoten *iterator = new TKnoten();

>
> HUH? Why are you creating another 'TKnoten' here?


How can I iterate over the whole list then without an extra object?


>> T daten = 0;
>> iterator = kopf;

>
> Again, you're immediately losing the value of 'iterator' that you
> just obtained from 'new'...
>
>> while (iterator->next != 0) {
>> if (iterator->index == i) {
>> daten = iterator->daten;
>> }
>> iterator = iterator->next;
>> }
>> delete iterator;

>
> Are you sure you need to 'delete' it here?


I thought that I have to delete everything I allocated with "new"?

Markus
 
Reply With Quote
 
Zachary Turner
Guest
Posts: n/a
 
      06-20-2007
On Jun 20, 3:19 pm, Markus Pitha <(E-Mail Removed)> wrote:
> Zachary Turner wrote:
> > I know this isn't your question, but you know that C++ already comes
> > with a linked list right? And also, it may have been better style to
> > declare your list on the stack instead of as a pointer and then using
> > new / delete.

>
> Where can I find this linked list? In the internet, I only find
> tutorials how to create a linked list.
> Which benefits does it have to create it on the stack?
> I thought that dynamically allocated space would be better.


#include <list>
using namespace std;

int main()
{
list<int> mylist;
mylist.push_back(1);
mylist.push_back(2);
mylist.push_back(3);
}

If you take this approach, there is a bit of a learning curve you will
have to overcome. Some keywords you can use to search for related
topics are:

STL (Standard Template Library) - a collection of generic containers
and algorithms provided with C++)
std::list - One of the generic collections in the STL. It's a doubly
linked list, and supports any time
iterator - The STL paradigm for iterating over any and all collections
in the STL.




Regarding memory allocation, stack based and heap based memory
allocation is totally separate.

Heap based - You specify exactly when it is created (with new), NULL
value is possible, and you specify exactly when it is deleted (with
delete)

Stack based - It is created the instant it is declared, NULL is not
possible, it is deleted immediately when it goes out of scope.
Consider this code:

if (true)
{
list<int>* pList = new list<int>();

pList->push_back(1);

delete pList;
}

Here you create a new instance of list immediately when you declare
it. You never make use of the null value, and you delete it
immediately before it goes out of scope. This is equivalent to what
stack based allocation provides. Therefore, the code is equivalent
to:

if (true)
{
list<int> list;
list.push_back(1);
}


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
how to Specializations of function Templates or Overloading Function templates with Templates ? recover C++ 2 07-25-2006 02:55 AM
Strings, Strings and Damned Strings Ben C Programming 14 06-24-2006 05:09 AM
Monster Templates - Question about Submitting Templates Fred HTML 1 09-26-2005 01:09 AM
Templates templates templates JKop C++ 3 07-21-2004 11:44 AM
using templates in templates John Harrison C++ 8 07-31-2003 12:00 PM



Advertisments