• Log InLog In
  • Register
Liquid`
Team Liquid Liquipedia
EDT 16:47
CEST 22:47
KST 05:47
  • Home
  • Forum
  • Calendar
  • Streams
  • Liquipedia
  • Features
  • Store
  • EPT
  • TL+
  • StarCraft 2
  • Brood War
  • Smash
  • Heroes
  • Counter-Strike
  • Overwatch
  • Liquibet
  • Fantasy StarCraft
  • TLPD
  • StarCraft 2
  • Brood War
  • Blogs
Forum Sidebar
Events/Features
News
Featured News
[ASL20] Ro24 Preview Pt2: Take-Off7[ASL20] Ro24 Preview Pt1: Runway132v2 & SC: Evo Complete: Weekend Double Feature4Team Liquid Map Contest #21 - Presented by Monster Energy9uThermal's 2v2 Tour: $15,000 Main Event18
Community News
Weekly Cups (Aug 18-24): herO dethrones MaxPax6Maestros of The Game—$20k event w/ live finals in Paris31Weekly Cups (Aug 11-17): MaxPax triples again!13Weekly Cups (Aug 4-10): MaxPax wins a triple6SC2's Safe House 2 - October 18 & 195
StarCraft 2
General
Geoff 'iNcontroL' Robinson has passed away Aligulac - Europe takes the podium A Eulogy for the Six Pool Weekly Cups (Aug 18-24): herO dethrones MaxPax 2v2 & SC: Evo Complete: Weekend Double Feature
Tourneys
Sparkling Tuna Cup - Weekly Open Tournament Maestros of The Game—$20k event w/ live finals in Paris Esports World Cup 2025 WardiTV Mondays RSL: Revival, a new crowdfunded tournament series
Strategy
Custom Maps
External Content
Mutation # 488 What Goes Around Mutation # 487 Think Fast Mutation # 486 Watch the Skies Mutation # 485 Death from Below
Brood War
General
ASL20 - worst advertising ever... BSL Polish World Championship 2025 20-21 September BGH Auto Balance -> http://bghmmr.eu/ ASL Season 20 Ro24 Groups Flash On His 2010 "God" Form, Mind Games, vs JD
Tourneys
[ASL20] Ro24 Group D [ASL20] Ro24 Group F [Megathread] Daily Proleagues [IPSL] CSLAN Review and CSLPRO Reimagined!
Strategy
Simple Questions, Simple Answers Fighting Spirit mining rates [G] Mineral Boosting Muta micro map competition
Other Games
General Games
Stormgate/Frost Giant Megathread Nintendo Switch Thread General RTS Discussion Thread Dawn of War IV Path of Exile
Dota 2
Official 'what is Dota anymore' discussion
League of Legends
Heroes of the Storm
Simple Questions, Simple Answers Heroes of the Storm 2.0
Hearthstone
Heroes of StarCraft mini-set
TL Mafia
TL Mafia Community Thread Vanilla Mini Mafia
Community
General
Russo-Ukrainian War Thread US Politics Mega-thread Things Aren’t Peaceful in Palestine The year 2050 European Politico-economics QA Mega-thread
Fan Clubs
INnoVation Fan Club SKT1 Classic Fan Club!
Media & Entertainment
Anime Discussion Thread Movie Discussion! [Manga] One Piece [\m/] Heavy Metal Thread
Sports
2024 - 2026 Football Thread Formula 1 Discussion TeamLiquid Health and Fitness Initiative For 2023
World Cup 2022
Tech Support
High temperatures on bridge(s) Gtx660 graphics card replacement Installation of Windows 10 suck at "just a moment"
TL Community
The Automated Ban List TeamLiquid Team Shirt On Sale
Blogs
RTS Design in Hypercoven
a11
Evil Gacha Games and the…
ffswowsucks
Breaking the Meta: Non-Stand…
TrAiDoS
INDEPENDIENTE LA CTM
XenOsky
[Girl blog} My fema…
artosisisthebest
Sharpening the Filtration…
frozenclaw
ASL S20 English Commentary…
namkraft
Customize Sidebar...

Website Feedback

Closed Threads



Active: 1276 users

C++ dynamic objects

Blogs > Freezard
Post a Reply
Normal
Freezard
Profile Blog Joined April 2007
Sweden1011 Posts
October 13 2010 12:37 GMT
#1
My teacher keeps on saying this is wrong although it works fine for me. He says that after I delete queue, the local queue pointer will be assigned the address of the new Queue-object and it won't be returned to Main and the original queue pointer because it's a copy.

But when I test it it does, both pointers have the same address all the time according to VS debug and I also see the capacity changes. My teacher told me to return the "copy" pointer from the function (queue = newQueue(queue)) which I tried and it did exactly the same thing.

Queue *queue = new Queue; //default capacity 10
newQueue(queue);

void newQueue(Queue *queue){
...
cin >> capacity;
delete queue;
queue = new Queue(capacity);
}

*
spinesheath
Profile Blog Joined June 2009
Germany8679 Posts
Last Edited: 2010-10-13 12:50:14
October 13 2010 12:48 GMT
#2
Well, he's right. You are assigning to a local pointer. Maybe VS does some magic so it works (like inlining since it's such a small function? Then again there should be no inlining in debug...).

You could use a reference to a Queue * as function argument. That way you would assign to the original pointer.
If you have a good reason to disagree with the above, please tell me. Thank you.
georgir
Profile Joined May 2009
Bulgaria253 Posts
October 13 2010 13:09 GMT
#3
It works in your case for one simple reason - the second time you create the object, it gets created at the same memory address as the first time, because that first object got deleted and the memory got released. Pure coincidence, in other words.
In general, this will not work. Test by commenting out the delete.
Mumblee
Profile Blog Joined May 2009
Canada256 Posts
October 13 2010 13:09 GMT
#4
Just because it works by accident (which could be for any number of reasons) doesn't mean you should do it.

My guess would be that your heap is allocating the new Queue where the old queue was deleted from.


outer_queue = new Queue //allocates memory at location X, constructs a queue object on top
newQueue(outer_queue)

void (newQueue* inner_queue)
{
delete inner_queue; //delete destructs the object at location X and allows the memory at
// X to be reused. inner_queue and outer_queue both still point at X
inner_queue = new Queue(capacitiy) //allocates memory at location X (because it was
// the most recently free'd block of memory) and
// constructs the new queue
}


Both inner_queue and outer_queue point at X, which is a valid object.

You got away with murder because your allocator just happened to allocate the new object at the same spot. If your allocator behaved differently and allocated the second Queue object at Y, inner_queue would point at Y and outer_queue would point at X, where X is no longer a valid Queue object.

TossFloss *
Profile Blog Joined February 2010
Canada606 Posts
October 13 2010 13:38 GMT
#5
Your teacher should ditch C++. >_< This makes me rage so much. Bloated OOP languages do not make good educational language for first time programmers.

Anyways, your teacher is right. Your code just happens to work in this particular instance.

Here's what you need to understand.
Queue * queue is a pointer to an object of type Queue.

Pointers and memory are not magical like crappy C++ makes them look. They are a number which points to an address in memory. The variable queue merely stores a number (e.g. 283840).

Let's break this down:

The type of variable---> Queue *<-- tells you this is a pointer queue <--- the name of your variable

Maybe you're wondering why we need to declare the type of variable queue stores i.e. what's up with the Queue in Queue *. Well we don't need to (more below). It's a nice feature called type checking which tries to make sure that when you compile your code you didn't accidentally think a queue object was a frog object and get them mixed up and then run code blocks like queue->jump(); queue->croak() and have your code crash terribly during runtime. Instead it spit out a nice compiler error.

However, you can shoot yourself in the foot like this:
void * queue
void * lets you make a pointer which can point to anything even a Frog.

Now let's go to the next important magical keyword in the C++ language. The magic new keyword.

new Queue;

This says to the operating system: Give me a chunk of memory large enough to fit a queue. Then the operating tries to allocate that much memory and gives you a memory address pointing to your memory.

Imagine that you are Miley Cyrus and your family has hundreds of fancy cars/vans/trucks - way too many for Miley's brain to keep track of. Some vehicles aren't available because they are being used, re-styled or someone like me stole them. So you being Miley Cyrus have a party with 6 other people that all need to fit into a car. So you need a vehicle for 7 people. You go to your butler and say "I need a vehicle that will fit exactly 7 people". He gives you the keys and parking spot number of such a vehicle. Your butler's like an OS and that parking spot number/keys is like a memory address.

Of course the OS might have no memory to give you (or might be really greedy and want to keep it all for itself) in which case it will tell you to gtfo. But this will probably never happen in any of your courses.

Please remember that the new keyword requests a fixed size of memory WHICH is known at compile time. You know how much memory is needed for a Queue object (your compiler does). Say your Queue object is a monster and takes up 256 bytes. Then new Queue is like saying: Operating System please set aside 256 bytes for my own personal use and give me the memory address.

So why does your code work? Because for some fluke of luck the queue you create in the newQueue function has the same memory address as the queue you deleted. If you wanna make it break: remove the delete queue line.
TL Android App Open Source http://www.teamliquid.net/forum/viewmessage.php?topic_id=265090
Frigo
Profile Joined August 2009
Hungary1023 Posts
Last Edited: 2010-10-13 14:06:28
October 13 2010 13:58 GMT
#6
You could use a reference to a pointer instead of a plain pointer in the parameters: void newQueue(Queue*& queue){...}. Or you can return a Queue* from your function: Queue* newQueue(Queue* oldqueue){...}; so that you can do q = newQueue(q) stuff.
Then it will modify the pointer. Obviously the way it is now, it does not.

Also, your code is rather fishy, use a constructor with std::istream& as parameter, or an operator >> to read from std::in; then all you need to do if you want to use it:

Queue q(std::in);
or
Queue* q = new Queue(std::in);
or
Queue q;
std::cin >> q;
or
Queue* q = new Queue();
std::cin >> (*q);
depending on how you want to use it.

I recommend you implement it with std::list (or std::vector for stack), that way you can easily insert/delete/resize without screwing around with pointers.
http://www.fimfiction.net/user/Treasure_Chest
tofucake
Profile Blog Joined October 2009
Hyrule19077 Posts
October 13 2010 14:17 GMT
#7
Put another variable declaration between the delete and instantiation, otherwise you'll get the first available address (the one you just cleared). Not hard to follow.
Liquipediaasante sana squash banana
Shenghi
Profile Joined August 2010
167 Posts
Last Edited: 2010-10-13 14:48:54
October 13 2010 14:41 GMT
#8
I am assuming that the OP is forced to use a queue by their teacher. Having said that, I agree that C++ should not be taught as a first language.

The reason it works is purely coincidental. I am inclined to agree with georgir and Mumblee that the reason it works in this particular case is that coincidentally the new Queue is created at the same memory address as the old one. There are three solutions:

1) Your teacher is right. Returning the local pointer and assigning that value would work.

Queue* q = new Queue();
q = newQueue(q);

Queue* newQueue(Queue* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = 0;
q = new Queue(c);
return q;
}

2) The C way. Pass a pointer to a pointer.

Queue* q = new Queue();
newQueue(&q);

void newQueue(Queue** q)
{
/*
...snip...
*/
Queue * ptr = (*q); // More readable
cin >> c;
delete ptr;
ptr = new Queue(c);
}

3) The C++ way, that has already been mentioned before: Pass a reference.

Queue* q = new Queue();
newQueue(q);

void newQueue(Queue&* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = new Queue(c);
}


Now since you obviously don't quite grasp the concept of pointers and passing by value yet, I would advise to go with the method your teacher suggest. In the end though it's a matter of style. Whichever way you decide to go with, make sure you understand what's happening and be consistent.

Having said all that, it horrifies me that your teacher is teaching you to delete an input parameter in a function that, by name, is claiming to create something. Please call the thing something along the lines of replaceQueue(...)
People are not born stupid, they choose to be stupid. If you made that choice, please change your mind.
Freezard
Profile Blog Joined April 2007
Sweden1011 Posts
October 13 2010 14:49 GMT
#9
Alright thanks guys, I understand the problem now. I used a return like teacher told me to and it's all good.

TossFloss: ROFL dude, I wish I had a teacher like you instead, you're funny and way better at explaining :D

I'm not a newbie to programming, I'm soon done with my 3 years CS program. However I'm newbie to C++ OOP and just read a introduction C++ course before this one. I know Java/C# OOP well but could never imagine something as easy as making a new object from an old would cause so many problems in C++. I'm used to memory management being all automatic... anyway thanks once again and I hope one day I won't be scared of pointers and instead find them useful!
Shenghi
Profile Joined August 2010
167 Posts
October 13 2010 15:02 GMT
#10
On October 13 2010 23:49 Freezard wrote:
Alright thanks guys, I understand the problem now. I used a return like teacher told me to and it's all good.

TossFloss: ROFL dude, I wish I had a teacher like you instead, you're funny and way better at explaining :D

I'm not a newbie to programming, I'm soon done with my 3 years CS program. However I'm newbie to C++ OOP and just read a introduction C++ course before this one. I know Java/C# OOP well but could never imagine something as easy as making a new object from an old would cause so many problems in C++. I'm used to memory management being all automatic... anyway thanks once again and I hope one day I won't be scared of pointers and instead find them useful!

The danger of switching from managed languages like Java and C# to C or C++ -- a danger your teacher should be aware of and should hammer on right from the start! -- is that these languages implicitly pass parameters by reference, and not by value. In a managed language your code would be correct because of this.

IN C AND C++ ALL PARAMETERS ARE COPIES OF WHAT YOU PASS!

If you pass an object, the function gets a copy of it. If you pass a pointer to an object, the function gets a copy of the pointer. References, even in C++, are a fancy way of hiding this. While that's nice and could most certainly make code more readable (especially in situations like these where you start having to use pointers to pointers) it can also be destructive if you don't understand what you're doing.
People are not born stupid, they choose to be stupid. If you made that choice, please change your mind.
Uranium
Profile Blog Joined May 2010
United States1077 Posts
October 13 2010 16:07 GMT
#11
On October 13 2010 22:38 TossFloss wrote:
Your teacher should ditch C++. >_< This makes me rage so much. Bloated OOP languages do not make good educational language for first time programmers..

What language would you prefer?

I learned C as my first language, followed by C++ and I feel like it's given me a better understanding of the hardware/software interaction than say Python or Java. Of course I am a computer engineer so I care about details (and speed!).
"Sentry imba! You see? YOU SEE??!!" - Sen | "Marauder die die!" - oGsMC | "Oh my god, she texted me back!" - Day[9]
Uranium
Profile Blog Joined May 2010
United States1077 Posts
Last Edited: 2010-10-13 16:10:52
October 13 2010 16:10 GMT
#12
On October 13 2010 23:41 Shenghi wrote:
3) The C++ way, that has already been mentioned before: Pass a reference.

Queue* q = new Queue();
newQueue(q);

void newQueue(Queue&* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = new Queue(c);
}

mind = blown I did not know you could reference a pointer.
"Sentry imba! You see? YOU SEE??!!" - Sen | "Marauder die die!" - oGsMC | "Oh my god, she texted me back!" - Day[9]
Uranium
Profile Blog Joined May 2010
United States1077 Posts
Last Edited: 2010-10-13 16:13:31
October 13 2010 16:13 GMT
#13
Also WHY are you doing it this way? You are essentially creating an object and then immediately destroying it to create another object?. You could just skip that step and just do

cin << cap;
Queue* q = new Queue(cap);

Unless of course this is just an intellectual exercise.
"Sentry imba! You see? YOU SEE??!!" - Sen | "Marauder die die!" - oGsMC | "Oh my god, she texted me back!" - Day[9]
NicolBolas
Profile Blog Joined March 2009
United States1388 Posts
October 13 2010 16:32 GMT
#14
Also, your code is rather fishy, use a constructor with std::istream& as parameter, or an operator >> to read from std::in; then all you need to do if you want to use it:


Ewww. That's awful coding practice. What if you wanted to create the object from a capacity value that wasn't pulled from a std:istream? Maybe something you compute based on the time of day? Or something else?

Object constructors should take the bare minimum necessary to build a working object of that type. No more. It places a dependency between that object and std::istream that is entirely unnecessary.
So you know, cats are interesting. They are kind of like girls. If they come up and talk to you, it's great. But if you try to talk to them, it doesn't always go so well. - Shigeru Miyamoto
Shenghi
Profile Joined August 2010
167 Posts
Last Edited: 2010-10-13 16:53:59
October 13 2010 16:47 GMT
#15
On October 14 2010 01:10 Uranium wrote:
Show nested quote +
On October 13 2010 23:41 Shenghi wrote:
3) The C++ way, that has already been mentioned before: Pass a reference.

Queue* q = new Queue();
newQueue(q);

void newQueue(Queue&* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = new Queue(c);
}

mind = blown I did not know you could reference a pointer.

You can, but it's not a very nice thing to do usually. It certainly wouldn't be my option of choice. But in the end a pointer is just a 4-byte (x86) value that can be passed like anything else, which includes passing by reference.

And to answer the which language first question: Java or C# like the OP apparently did get first would be fine. Not all of us grew up in an age where these were non-existent, or where it was vital for every programmer to understand the underlying architecture. In this day and age, however, it can give quite the edge as most CS graduates never really learn the lower level languages.

I personally did learn C as a first language and then C++, but I taught myself. A couple years late, I'm now attending uni and see how many problems other students have with Java already. If C or C++ was the first language they learned then even more people would fail.
People are not born stupid, they choose to be stupid. If you made that choice, please change your mind.
TossFloss *
Profile Blog Joined February 2010
Canada606 Posts
Last Edited: 2010-10-13 17:12:18
October 13 2010 17:03 GMT
#16
On October 14 2010 01:07 Uranium wrote:
Show nested quote +
On October 13 2010 22:38 TossFloss wrote:
Your teacher should ditch C++. >_< This makes me rage so much. Bloated OOP languages do not make good educational language for first time programmers..

What language would you prefer?

I learned C as my first language, followed by C++ and I feel like it's given me a better understanding of the hardware/software interaction than say Python or Java. Of course I am a computer engineer so I care about details (and speed!).


Straight up C with K&R as the course text.

And to answer the which language first question: Java or C# like the OP apparently did get first would be fine. Not all of us grew up in an age where these were non-existent, or where it was vital for every programmer to understand the underlying architecture. In this day and age, however, it can give quite the edge as most CS graduates never really learn the lower level languages.


If I interview a CS graduate who doesn't understand memory allocation after four years of supposed education, they do not get the job. Too many programmers possess zero knowledge of how their program allocate and reference memory, and consequently their programs are slow, bloated and buggy.
TL Android App Open Source http://www.teamliquid.net/forum/viewmessage.php?topic_id=265090
waxypants
Profile Blog Joined September 2009
United States479 Posts
Last Edited: 2010-10-13 17:05:36
October 13 2010 17:04 GMT
#17
On October 14 2010 01:47 Shenghi wrote:
Show nested quote +
On October 14 2010 01:10 Uranium wrote:
On October 13 2010 23:41 Shenghi wrote:
3) The C++ way, that has already been mentioned before: Pass a reference.

Queue* q = new Queue();
newQueue(q);

void newQueue(Queue&* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = new Queue(c);
}

mind = blown I did not know you could reference a pointer.

You can, but it's not a very nice thing to do usually. It certainly wouldn't be my option of choice. But in the end a pointer is just a 4-byte (x86) value that can be passed like anything else, which includes passing by reference.

And to answer the which language first question: Java or C# like the OP apparently did get first would be fine. Not all of us grew up in an age where these were non-existent, or where it was vital for every programmer to understand the underlying architecture. In this day and age, however, it can give quite the edge as most CS graduates never really learn the lower level languages.

I personally did learn C as a first language and then C++, but I taught myself. A couple years late, I'm now attending uni and see how many problems other students have with Java already. If C or C++ was the first language they learned then even more people would fail.


Meh I think building up from the basics of C is much better than trying to come down to the basics after learning a higher level language such as Java. People who start at Java and try to go down any lower really have no idea of what is going on underneath their code. When you peel off the layers of abstraction that Java adds, there is nothing left for those guys. Someone who knows C can easily bump up to a higher level language like C++ or Java.
dvide
Profile Joined March 2010
United Kingdom287 Posts
October 13 2010 17:15 GMT
#18
Best option would be to implement The Big Three properly and then just create your Queue objects on the stack. There is probably no reason for them to be on the heap for you. If you want a factory convenience function just return it by value. Your compiler will perform return value optimization (RVO).


Queue createQueue()
{
...
std::cin >> capacity;
return Queue(capacity);
}

Queue queue; // default capacity 10
...
queue = createQueue();


More simples.
TossFloss *
Profile Blog Joined February 2010
Canada606 Posts
Last Edited: 2010-10-13 17:26:24
October 13 2010 17:19 GMT
#19
On October 14 2010 02:04 waxypants wrote:
Show nested quote +
On October 14 2010 01:47 Shenghi wrote:
On October 14 2010 01:10 Uranium wrote:
On October 13 2010 23:41 Shenghi wrote:
3) The C++ way, that has already been mentioned before: Pass a reference.

Queue* q = new Queue();
newQueue(q);

void newQueue(Queue&* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = new Queue(c);
}

mind = blown I did not know you could reference a pointer.

You can, but it's not a very nice thing to do usually. It certainly wouldn't be my option of choice. But in the end a pointer is just a 4-byte (x86) value that can be passed like anything else, which includes passing by reference.

And to answer the which language first question: Java or C# like the OP apparently did get first would be fine. Not all of us grew up in an age where these were non-existent, or where it was vital for every programmer to understand the underlying architecture. In this day and age, however, it can give quite the edge as most CS graduates never really learn the lower level languages.

I personally did learn C as a first language and then C++, but I taught myself. A couple years late, I'm now attending uni and see how many problems other students have with Java already. If C or C++ was the first language they learned then even more people would fail.


Meh I think building up from the basics of C is much better than trying to come down to the basics after learning a higher level language such as Java. People who start at Java and try to go down any lower really have no idea of what is going on underneath their code. When you peel off the layers of abstraction that Java adds, there is nothing left for those guys. Someone who knows C can easily bump up to a higher level language like C++ or Java.


My other issue with C++ is that it's bloated with keywords and higher-level concepts.

For example, a new learner get beffedudled keeping of tracking of: what's this namespace thing and why do I care; what's up with these magic << and >> operators; how do I make sense of objects; so I can functions with objects and functions without objects; constructors and destructors; class variables.

At the same time they have to figure out the building blocks of programs (for, while, if, else, char, int, array, ...) and language syntax. And really it's too much information to absorb and digest.

As a reference: here's a list of C++ keywords contrast to the list of C keywords.
TL Android App Open Source http://www.teamliquid.net/forum/viewmessage.php?topic_id=265090
Manit0u
Profile Blog Joined August 2004
Poland17301 Posts
October 13 2010 17:34 GMT
#20
Heh, the very first programming language I had to learn was Turbo Pascal Man I hated this shit...
Time is precious. Waste it wisely.
Shenghi
Profile Joined August 2010
167 Posts
Last Edited: 2010-10-13 17:50:54
October 13 2010 17:48 GMT
#21
Too lazy to quote people:

@TossFloss

Eventually you'll run out of graduates to hire. In a couple of years nobody will learn lower level languages anymore, and unless they take a minor that covers architecture they will not know anything. I agree that they should know. When looking at the university that I am attending, after two years those who did not start their studies with prior knowledge have only a vague notion of scope and none whatsoever of ownership. And I didn't even start about memory yet. It's sad but unfortunately true.

I have to agree that C would be better as a first language than C++ for exactly the reasons you're giving.

@dvide

Please, pretty please, do not return objects by value. What if I decided to make a queue of size MAX_INT?

@waxypants

You have a point, but it would require a complete overhaul of how people are currently taught.

@nobody in particular

The (sad) truth is that many companies don't care whether or not their grads understand things like memory allocation. With the current systems a bloated app written in a managed language will often run "fast enough," as long as they're not too buggy. A CS grad who knows Java and has a vague notion of basics is also a lot cheaper than someone who knows their stuff. Not to mention faster (because he isn't nice and tidy.)

To be honest it doesn't matter which languages are taught. Most fresh CS grads are not competent programmers regardless of which language they have been taught. They would of course lack experience, but more importantly most universities don't teach their CS students basic concepts, or how to reason about programs. In the end the language of choice is just a tool.

[BTW]
We're going way off topic :p

[edit]
Based on what most companies are looking for, any managed language as first language would be better than C or C++. When it comes to competence I wholeheartedly agree that C should be the first language.
People are not born stupid, they choose to be stupid. If you made that choice, please change your mind.
Slithe
Profile Blog Joined February 2007
United States985 Posts
October 13 2010 17:48 GMT
#22
On October 14 2010 02:19 TossFloss wrote:
Show nested quote +
On October 14 2010 02:04 waxypants wrote:
On October 14 2010 01:47 Shenghi wrote:
On October 14 2010 01:10 Uranium wrote:
On October 13 2010 23:41 Shenghi wrote:
3) The C++ way, that has already been mentioned before: Pass a reference.

Queue* q = new Queue();
newQueue(q);

void newQueue(Queue&* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = new Queue(c);
}

mind = blown I did not know you could reference a pointer.

You can, but it's not a very nice thing to do usually. It certainly wouldn't be my option of choice. But in the end a pointer is just a 4-byte (x86) value that can be passed like anything else, which includes passing by reference.

And to answer the which language first question: Java or C# like the OP apparently did get first would be fine. Not all of us grew up in an age where these were non-existent, or where it was vital for every programmer to understand the underlying architecture. In this day and age, however, it can give quite the edge as most CS graduates never really learn the lower level languages.

I personally did learn C as a first language and then C++, but I taught myself. A couple years late, I'm now attending uni and see how many problems other students have with Java already. If C or C++ was the first language they learned then even more people would fail.


Meh I think building up from the basics of C is much better than trying to come down to the basics after learning a higher level language such as Java. People who start at Java and try to go down any lower really have no idea of what is going on underneath their code. When you peel off the layers of abstraction that Java adds, there is nothing left for those guys. Someone who knows C can easily bump up to a higher level language like C++ or Java.


My other issue with C++ is that it's bloated with keywords and higher-level concepts.

For example, a new learner get beffedudled keeping of tracking of: what's this namespace thing and why do I care; what's up with these magic << and >> operators; how do I make sense of objects; so I can functions with objects and functions without objects; constructors and destructors; class variables.

At the same time they have to figure out the building blocks of programs (for, while, if, else, char, int, array, ...) and language syntax. And really it's too much information to absorb and digest.

As a reference: here's a list of C++ keywords contrast to the list of C keywords.


I think we can all agree that C++ is terrible as a first language. It does not seem that C++ is the OP's first language anyway.

With regards to whether Java or C is better, it really is a question of teaching style. Is it better to learn the high level concepts first, without the clutter of low level implementation? Or is it better to understand the underlying mechanics and build up to higher level understanding?

My personal opinion is that the first approach (i.e. Java or python first) is better. My reasoning is that we want to reduce the number of things that one has to learn to start accomplishing basic tasks, and it's easier to build from a less complex core of knowledge. C++ is obviously terrible in this regard. C is nice in that it exposes the underlying hardware in a more clean fashion, but it may still be more frustrating for someone to have to deal with it if they're just getting started. I also do not think there is an issue with the transition from Java to C, as long as it is approached correctly. You just have to gradually peel the onion of computer science, one layer at a time.

In the end, both methods are perfectly viable. Everyone has to learn all the basics from low to high at some point, so whichever direction you go, you should end up with the same result, if done correctly.
Freezard
Profile Blog Joined April 2007
Sweden1011 Posts
October 13 2010 17:55 GMT
#23
On October 14 2010 01:13 Uranium wrote:
Also WHY are you doing it this way? You are essentially creating an object and then immediately destroying it to create another object?. You could just skip that step and just do

cin << cap;
Queue* q = new Queue(cap);

Unless of course this is just an intellectual exercise.

The program starts with a Queue with default cap and then you can choose to create a new one on a menu. It wasn't even necessary in the assignment to make a new one, you were supposed to let them choose capacity one time and then stick with it, but yea... felt cheap to me.

Also I'm happy I started with Java. Well that's not entirely true because the first language we learn is Haskell which is a functional language. But I had enough trouble with Java in the beginning that I feel that if I had started with C++ instead of Java I woulda ragequit school as soon as we had to learn pointers.

I did read two courses in digital electrics and computer engineering where we were programming in assembly (along with C later on) which is as close to machine language you can come. It was really fun because we got to program a drill among other things but I also learned a lot about memory management. I really didn't know everything was passed by value in C++, thanks for pointing that out because it makes a lot more sense now.

I'll go on finishing my second assignment which has been a lot easier thanks to my new knowledge <3 TL!
Frigo
Profile Joined August 2009
Hungary1023 Posts
Last Edited: 2010-10-13 18:58:39
October 13 2010 18:36 GMT
#24
Ewww. That's awful coding practice. What if you wanted to create the object from a capacity value that wasn't pulled from a std:istream? Maybe something you compute based on the time of day? Or something else?

You're not limited to one constructor. Feel free to write additional ones that make sense in light of the given problem. std::istream in this case. Time of the day / CPU time in the case of a random generator. Or in the case of one of my classes, Image<double>("filename.png", ImageRGB), Image<double>(640, 480, ImageRGB), Image<double>(sourceImage), et cetera.

Object constructors should take the bare minimum necessary to build a working object of that type. No more.

Where do you get this silly idea? What you have described is essentially constructing an object via the default constructor and a load of setter functions, which I'm pretty sure is an antipattern, causes redundant assigments, and is discouraged by a lot of common practices, including Effective C++.
You should write constructors and public access functions and operators that are intuitive, easy to use, make sense within the context of the problem, and are well documented.
In case you were thinking about default constructors, I completely agree.

It places a dependency between that object and std::istream that is entirely unnecessary.

Lot of the times istream is already included, so that's usually not a problem. In the cases it does cause problems, you are doing something very very wrong.
And just because a completely legitimate, easy and clever way to initialize an object involves a dependency, is no grounds to outright disregard it. (Yes, circular dependencies are evil, but are easily resolved with predeclarations, template trickery or some other way)
http://www.fimfiction.net/user/Treasure_Chest
Manit0u
Profile Blog Joined August 2004
Poland17301 Posts
October 13 2010 18:43 GMT
#25
On October 14 2010 02:48 Slithe wrote:
Show nested quote +
On October 14 2010 02:19 TossFloss wrote:
On October 14 2010 02:04 waxypants wrote:
On October 14 2010 01:47 Shenghi wrote:
On October 14 2010 01:10 Uranium wrote:
On October 13 2010 23:41 Shenghi wrote:
3) The C++ way, that has already been mentioned before: Pass a reference.

Queue* q = new Queue();
newQueue(q);

void newQueue(Queue&* q)
{
/*
...snip...
*/
cin >> c;
delete q;
q = new Queue(c);
}

mind = blown I did not know you could reference a pointer.

You can, but it's not a very nice thing to do usually. It certainly wouldn't be my option of choice. But in the end a pointer is just a 4-byte (x86) value that can be passed like anything else, which includes passing by reference.

And to answer the which language first question: Java or C# like the OP apparently did get first would be fine. Not all of us grew up in an age where these were non-existent, or where it was vital for every programmer to understand the underlying architecture. In this day and age, however, it can give quite the edge as most CS graduates never really learn the lower level languages.

I personally did learn C as a first language and then C++, but I taught myself. A couple years late, I'm now attending uni and see how many problems other students have with Java already. If C or C++ was the first language they learned then even more people would fail.


Meh I think building up from the basics of C is much better than trying to come down to the basics after learning a higher level language such as Java. People who start at Java and try to go down any lower really have no idea of what is going on underneath their code. When you peel off the layers of abstraction that Java adds, there is nothing left for those guys. Someone who knows C can easily bump up to a higher level language like C++ or Java.


My other issue with C++ is that it's bloated with keywords and higher-level concepts.

For example, a new learner get beffedudled keeping of tracking of: what's this namespace thing and why do I care; what's up with these magic << and >> operators; how do I make sense of objects; so I can functions with objects and functions without objects; constructors and destructors; class variables.

At the same time they have to figure out the building blocks of programs (for, while, if, else, char, int, array, ...) and language syntax. And really it's too much information to absorb and digest.

As a reference: here's a list of C++ keywords contrast to the list of C keywords.


I think we can all agree that C++ is terrible as a first language. It does not seem that C++ is the OP's first language anyway.

With regards to whether Java or C is better, it really is a question of teaching style. Is it better to learn the high level concepts first, without the clutter of low level implementation? Or is it better to understand the underlying mechanics and build up to higher level understanding?

My personal opinion is that the first approach (i.e. Java or python first) is better. My reasoning is that we want to reduce the number of things that one has to learn to start accomplishing basic tasks, and it's easier to build from a less complex core of knowledge. C++ is obviously terrible in this regard. C is nice in that it exposes the underlying hardware in a more clean fashion, but it may still be more frustrating for someone to have to deal with it if they're just getting started. I also do not think there is an issue with the transition from Java to C, as long as it is approached correctly. You just have to gradually peel the onion of computer science, one layer at a time.

In the end, both methods are perfectly viable. Everyone has to learn all the basics from low to high at some point, so whichever direction you go, you should end up with the same result, if done correctly.


Well, I'm not a competent programmer myself, but I did try to learn a couple languages myself and I hate to say after a while that going structural (C) -> object oriented (Java) is easier than the other way around. Object oriented programming (especially when you can use classes) seems to me faster/easier than structural and if you learn OO first, you might meet a lot of barriers when you try ST and have to do a lot of things "manually".
Time is precious. Waste it wisely.
dvide
Profile Joined March 2010
United Kingdom287 Posts
Last Edited: 2010-10-13 19:04:02
October 13 2010 19:02 GMT
#26
On October 14 2010 02:48 Shenghi wrote:
@dvide

Please, pretty please, do not return objects by value. What if I decided to make a queue of size MAX_INT?

Then you'll make a big queue, but no extra copies of it will be made from the factory function due to RVO as I mentioned. If you want to avoid copies in other contexts then pass it around as a reference, but do try to keep it on the stack unless you have a good reason. For sure sometimes it is best to put an expensive-to-copy object on the heap if you'd have no other choice than to unnecessarily copy it often, but this is messy and should not be default behaviour (and thankfully it's resolved in the upcoming changes to the C++ standard). Plus in a lot of these cases you can get away with using a specialised swap function (which you will probably have anyway if you implement the copy-and-swap idiom) to steal resources. But in most use cases it will probably be faster to access your object directly than through a pointer in some premature effort to merely to avoid a few minor copies.

It's certainly better than putting all deep-copy objects onto the heap all of the time and using pointer semantics everywhere in a paranoid attempt to avoid copies without even measuring it. You will get none of the benefits of using automatic variables for resource management (RAII). This will lead to more problems in the long term, especially when you start getting into requiring exception safety. Values are your friends.

On October 14 2010 03:36 Frigo wrote:
Show nested quote +
Ewww. That's awful coding practice. What if you wanted to create the object from a capacity value that wasn't pulled from a std:istream? Maybe something you compute based on the time of day? Or something else?

You're not limited to one constructor. Feel free to write additional ones that make sense in light of the given problem. std::istream in this case. Time of the day / CPU time in the case of a random generator. Or in the case of one of my classes, Image<double>("filename.png", ImageRGB), Image<double>(640, 480, ImageRGB), Image<double>(sourceImage), et cetera.

Show nested quote +
Object constructors should take the bare minimum necessary to build a working object of that type. No more.

Where do you get this silly idea? What you have described is essentially constructing an object via the default constructor and a load of setter functions, which I'm pretty sure is an antipattern, causes redundant overwrites, and is discouraged by a lot of common practices, including Effective C++.
You should write constructors and public access functions and operators that are intuitive, easy to use, make sense within the context of the problem, and are well documented.
In case you were thinking about default constructors, I completely agree.

Show nested quote +
It places a dependency between that object and std::istream that is entirely unnecessary.

Lot of the times istream is already included, so that's usually not a problem. In the cases it does cause problems, you are doing something very very wrong.
And just because a completely legitimate, easy and clever way to initialize an object involves a dependency, is no grounds to outright disregard it. (Yes, circular dependencies are evil, but are easily resolved with predeclarations, template trickery or some other way)

If all that your object requires is an A to construct itself, then just take an A in the constructor. Don't take a B and then ask it to get an A for you. Then creates an unnecessary coupling with B. See the Law of Demeter. If some complex but frequent procedure is needed to build an object then just use some creational pattern. This separates concerns nicely.
Shenghi
Profile Joined August 2010
167 Posts
October 13 2010 19:13 GMT
#27
@dvide

Whoops, I completely read over the RVO part of your post. Sorry. I still wouldn't do it that way, but that's simply a matter of taste.

I do agree that when something doesn't absolutely need to be on the heap, it shouldn't be.
People are not born stupid, they choose to be stupid. If you made that choice, please change your mind.
LastWish
Profile Blog Joined September 2004
2013 Posts
Last Edited: 2010-10-13 20:20:36
October 13 2010 20:19 GMT
#28

Queue *queue = new Queue; //default capacity 10
newQueue(queue);

void newQueue(Queue *queue){
...
cin >> capacity;
delete queue;
queue = new Queue(capacity);
}

This code makes me wanna puke. Blheh.
Please learn to program in a way dvide suggested :

On October 14 2010 02:15 dvide wrote:

Queue createQueue()
{
...
std::cin >> capacity;
return Queue(capacity);
}

Queue queue; // default capacity 10
...
queue = createQueue();



As a good rule try to never use new.
If you have to use it in a wrapper in constructor and make sure to delete the object in destructor.
Or use boost::shared_ptr<your_type>, then you don't have to worry about destructions. This will actually also start to get useful later when you will want to make your objects copy-able, but with some parts referencing to the same object(now too compicated for beginners).

- It's all just treason - They bring me down with their lies - Don't know the reason - My life is fire and ice -
Freezard
Profile Blog Joined April 2007
Sweden1011 Posts
Last Edited: 2010-10-13 20:51:13
October 13 2010 20:48 GMT
#29
On October 14 2010 05:19 LastWish wrote:

Queue *queue = new Queue; //default capacity 10
newQueue(queue);

void newQueue(Queue *queue){
...
cin >> capacity;
delete queue;
queue = new Queue(capacity);
}

This code makes me wanna puke. Blheh.
Please learn to program in a way dvide suggested :

Show nested quote +
On October 14 2010 02:15 dvide wrote:

Queue createQueue()
{
...
std::cin >> capacity;
return Queue(capacity);
}

Queue queue; // default capacity 10
...
queue = createQueue();



As a good rule try to never use new.
If you have to use it in a wrapper in constructor and make sure to delete the object in destructor.
Or use boost::shared_ptr<your_type>, then you don't have to worry about destructions. This will actually also start to get useful later when you will want to make your objects copy-able, but with some parts referencing to the same object(now too compicated for beginners).


Doesn't work I get heap error after I create new queue and try to enqueue an item T_T

How can you assign an object to a variable without using new? That makes no sense since the new word allocated memory.

enqueue(&queue);
void enqueue(Queue *queue){
queue->enqueue(element);
}
imDerek
Profile Blog Joined August 2007
United States1944 Posts
October 13 2010 20:50 GMT
#30
you want to pass in Queue** or Queue*& if u want to change Queue*
Least favorite progamers: Leta, Zero, Mind, Shine, free, really <-- newly added
Freezard
Profile Blog Joined April 2007
Sweden1011 Posts
October 13 2010 20:58 GMT
#31
On October 14 2010 05:50 imDerek wrote:
you want to pass in Queue** or Queue*& if u want to change Queue*

Wut? Excuse me? Do you have to use double pointers when I don't even understand single pointers? I'm sure that's a better way but also more complicated...

And yes btw it has to be a dynamic object which I assume Queue queue can never be (since you can't use new/delete on it).
Frigo
Profile Joined August 2009
Hungary1023 Posts
Last Edited: 2010-10-13 21:58:38
October 13 2010 21:39 GMT
#32
On October 14 2010 04:02 dvide wrote:
If all that your object requires is an A to construct itself, then just take an A in the constructor. Don't take a B and then ask it to get an A for you. Then creates an unnecessary coupling with B. See the Law of Demeter. If some complex but frequent procedure is needed to build an object then just use some creational pattern. This separates concerns nicely.

Cool, didn't know about this particular (anti)pattern yet.
Though I fail to recognize how it applies in this particular case. std::istream does not contain the integer we read in, there is absolutely no coupling between the three. Especially since the integer is not an object, only an instance of a primitive type, a constant return value we will simply discard (more properly, store in another integer). We can not implement the behavior in std::istream either, it simply can't do anything with our Queue class. No need for any wrappers either.
http://www.fimfiction.net/user/Treasure_Chest
dvide
Profile Joined March 2010
United Kingdom287 Posts
Last Edited: 2010-10-14 00:22:37
October 13 2010 22:39 GMT
#33
On October 14 2010 05:48 Freezard wrote:
Doesn't work I get heap error after I create new queue and try to enqueue an item T_T

How can you assign an object to a variable without using new? That makes no sense since the new word allocated memory.

Your class should define a copy constructor and assignment operator that handles the semantics of this operation properly (and a destructor, but I'll assume you already have that). This is probably the most important thing to understand in C++ (trust me), so I'd make it a priority. It's a little bit complicated, but once you've got it down you'll understand why and it will save you a lot of headaches down the road. Be warned, for it may even make you enjoy programming in C++

The compiler generates a hidden, default implementation of these functions for you (which is why it compiles), but in this case the default implementations are incorrect and that is what is ultimately causing your heap errors. The default generated functions simply do a memberwise copy of your object's variables, but what you want instead is deep-copy semantics.

If your queue object owns some memory (which I assume it does), it will have a pointer member variable. The default generated copy constructor and assignment operator functions simply copy the pointer value to another queue object, which means that now two queue objects share ownership of the same memory location. When one of your queue objects is destroyed its destructor is called, which will then proceed to delete its memory. This will leave your other queue object with a dangling pointer to already freed memory, and when accessed you will therefore get undefined behaviour (such as your heap error).

What you want to do instead is create a copy constructor that allocates more memory for itself and copies the old data into it. So now each queue object is unique and owns its own memory, but the value of the two queues are still semantically identical (i.e. a copy). The assignment operator should do essentially the same thing. It needs to free it's own memory and allocate itself more memory and then copy the rhs (right hand side) data into it.

The assignment operator can actually be written in-terms of the copy constructor and destructor (and a swap function), which is very nice for code reuse. This is the cleanest way to write the functions, and is referred to as the copy-and-swap idiom. Even though the above is a lot of explanation, the actual idiom is quite small and takes minimal effort to implement.


class Queue
{
private:
std::size_t m_capacity; // basically an unsigned int
int* m_data;

public:
Queue(std::size_t capacity)
// an initialisation list (google it if you don't know it)
: m_capacity(capacity), m_data( new int[capacity]() )
{
}

// Copy constructor
Queue(const Queue& rhs) // must take rhs param by const ref
// Allocates its own memory area large enough to hold rhs's data ...
: m_capacity(rhs.m_capacity), m_data( new int[rhs.m_capacity] )
{
// ... and then copies rhs's data into it
std::copy( rhs.m_data, rhs.m_data + m_capacity, m_data );

// include <algorithm> for std::copy
}

// Assignment operator
// Take rhs param by value, it invokes the copy constructor above
Queue& operator=(Queue rhs)
{
swap(*this, rhs); // swap our contents with rhs (a cheap operation)
return *this;

// rhs goes out of scope, invoking its destructor
// (it will free the memory we used to own)
}

// Swap our members
friend void swap(Queue& a, Queue& b)
{
using std::swap; // include <utility> for std::swap
swap(a.m_capacity, b.m_capacity);
swap(a.m_data, b.m_data);
}

// Free the memory we own
~Queue()
{
delete [] m_data;
}

... enqueue functions, etc.
... I'm unconcerned with that, as this is just about managing resources
... tried to keep this example as simple as possible
}



Queue q1;
Queue q2(q1); // Invokes copy constructor
Queue q3 = q1; // Invokes copy constructor (exactly the same as above)
q1 = q2; // Invokes assignment operator (not an initialisation)


Hope that all makes sense.
LastWish
Profile Blog Joined September 2004
2013 Posts
October 13 2010 22:56 GMT
#34

// Assignment operator
Queue& operator=(Queue rhs) // take param by value, it invokes the copy constructor above
{
swap(*this, rhs); // swap our contents with the rhs (a cheap operation)
return *this;
// rhs goes out of scope, invoking its destructor (it will free the memory we used to own)
}

Actually this seems to be wrong.
Queue& operator=(Queue& rhs)
If you omit the & you may get into trouble because :
- rhs will be a temporal object
- rhs might not be deallocated properly if this == &rhs

Quick google find :
http://www.fredosaurus.com/notes-cpp/oop-overloading/overloadassign.html
- It's all just treason - They bring me down with their lies - Don't know the reason - My life is fire and ice -
dvide
Profile Joined March 2010
United Kingdom287 Posts
October 13 2010 22:59 GMT
#35
On October 14 2010 06:39 Frigo wrote:
Show nested quote +
On October 14 2010 04:02 dvide wrote:
If all that your object requires is an A to construct itself, then just take an A in the constructor. Don't take a B and then ask it to get an A for you. Then creates an unnecessary coupling with B. See the Law of Demeter. If some complex but frequent procedure is needed to build an object then just use some creational pattern. This separates concerns nicely.

Cool, didn't know about this particular (anti)pattern yet.
Though I fail to recognize how it applies in this particular case. std::istream does not contain the integer we read in, there is absolutely no coupling between the three. Especially since the integer is not an object, only an instance of a primitive type, a constant return value we will simply discard (more properly, store in another integer). We can not implement the behavior in std::istream either, it simply can't do anything with our Queue class. No need for any wrappers either.

The principle of least knowledge as I understand it is like this: if you want some money from a customer don't ask for their wallet so that you can take the money out by yourself. Just ask for money directly. There is no reason for you to be coupled to the wallet in any way. It makes it harder to unit test the class in isolation for example, since now you have a dependency on wallet that is not strictly needed. Indeed, you only added the dependency for a convenience case, so a simple factory function would serve us better in that case.
LastWish
Profile Blog Joined September 2004
2013 Posts
Last Edited: 2010-10-13 23:19:33
October 13 2010 23:14 GMT
#36

private:
int* m_data;
std::size_t m_capacity; // basically an unsigned int

public:
Queue(std::size_t capacity)
// an initialisation list (google it if you don't know it)
: m_capacity(capacity), m_data( new int[capacity]() )
{
}


Initialisation list isn't initialized according to the order in which they are mentioned in the constructor, rather the order in the class definition.

private:
std::size_t m_capacity; // basically an unsigned int
int* m_data;

In this case you don't even have to use initialization lists, since it makes no performance gain.
Although your stuff works since you used new int[capacity] and not m_capacity.
- It's all just treason - They bring me down with their lies - Don't know the reason - My life is fire and ice -
dvide
Profile Joined March 2010
United Kingdom287 Posts
Last Edited: 2010-10-14 00:24:00
October 13 2010 23:17 GMT
#37
On October 14 2010 07:56 LastWish wrote:

// Assignment operator
Queue& operator=(Queue rhs) // take param by value, it invokes the copy constructor above
{
swap(*this, rhs); // swap our contents with the rhs (a cheap operation)
return *this;
// rhs goes out of scope, invoking its destructor (it will free the memory we used to own)
}

Actually this seems to be wrong.
Queue& operator=(Queue& rhs)
If you omit the & you may get into trouble because :
- rhs will be a temporal object
- rhs might not be deallocated properly if this == &rhs

Quick google find :
http://www.fredosaurus.com/notes-cpp/oop-overloading/overloadassign.html

Temporal object. Sweet, is that out of star trek?

The copy-and-swap idiom must always make a temporary copy. So you might as well copy it in the parameter list because then the compiler can elide it sometimes if it comes from an rvalue. See this article: http://cpp-next.com/archive/2009/08/want-speed-pass-by-value/

Self assignment does not lead to a bug in this case. It's not as efficient as specifically checking for it, because we still must make a copy. But we can't check for it if we take the parameter by value, this is true. But we shouldn't optimise for this minor corner case when we get much more gains from copy elision here (as Dave Abrahams mentions in a comment of the article I linked to).

That assignment operator link you sent also does not provide a strong exception guarantee, where as the copy and swap idiom does. If new char throws a bad_alloc exception, for instance the state of the object is left all messed up.

On October 14 2010 08:14 LastWish wrote:
Initialisation list isn't initialized according to the order in which they are mentioned in the constructor, rather the order in the class definition.

Thanks, I've corrected that.

EDIT: Also fixed the call to std::copy. Had the parameters wrong.
Normal
Please log in or register to reply.
Live Events Refresh
Next event in 3h 13m
[ Submit Event ]
Live Streams
Refresh
StarCraft 2
UpATreeSC 130
Nathanias 107
ProTech105
JuggernautJason57
StarCraft: Brood War
Dewaltoss 78
ajuk12(nOOB) 18
NaDa 11
Beast 2
Dota 2
Pyrionflax231
monkeys_forever228
capcasts157
League of Legends
Reynor108
Counter-Strike
Stewie2K634
Heroes of the Storm
Liquid`Hasu501
Other Games
Grubby2643
FrodaN843
C9.Mang0198
IndyStarCraft 160
ToD121
ZombieGrub95
markeloff70
Trikslyr41
Organizations
StarCraft 2
angryscii 24
Other Games
BasetradeTV11
StarCraft 2
Blizzard YouTube
StarCraft: Brood War
BSLTrovo
sctven
[ Show 18 non-featured ]
StarCraft 2
• StrangeGG 56
• Migwel
• AfreecaTV YouTube
• sooper7s
• intothetv
• Kozan
• IndyKCrew
• LaughNgamezSOOP
StarCraft: Brood War
• Pr0nogo 6
• iopq 1
• STPLYoutube
• ZZZeroYoutube
• BSLYoutube
Dota 2
• masondota21374
• Noizen39
League of Legends
• Doublelift2774
Counter-Strike
• imaqtpie1010
Other Games
• Shiphtur165
Upcoming Events
Replay Cast
3h 13m
The PondCast
13h 13m
WardiTV Summer Champion…
14h 13m
herO vs MaxPax
Clem vs Classic
Replay Cast
1d 3h
LiuLi Cup
1d 14h
MaxPax vs TriGGeR
ByuN vs herO
Cure vs Rogue
Classic vs HeRoMaRinE
Cosmonarchy
1d 19h
OyAji vs Sziky
Sziky vs WolFix
WolFix vs OyAji
Big Brain Bouts
1d 19h
Iba vs GgMaChine
TriGGeR vs Bunny
Reynor vs Classic
Serral vs Clem
BSL Team Wars
1d 22h
Team Hawk vs Team Dewalt
BSL Team Wars
1d 22h
Team Hawk vs Team Bonyth
SC Evo League
2 days
TaeJa vs Cure
Rogue vs threepoint
ByuN vs Creator
MaNa vs Classic
[ Show More ]
Maestros of the Game
2 days
ShoWTimE vs Cham
GuMiho vs Ryung
Zoun vs Spirit
Rogue vs MaNa
[BSL 2025] Weekly
2 days
SC Evo League
3 days
Maestros of the Game
3 days
SHIN vs Creator
Astrea vs Lambo
Bunny vs SKillous
HeRoMaRinE vs TriGGeR
BSL Team Wars
3 days
Team Bonyth vs Team Sziky
BSL Team Wars
3 days
Team Dewalt vs Team Sziky
Monday Night Weeklies
4 days
Replay Cast
5 days
Sparkling Tuna Cup
5 days
Liquipedia Results

Completed

CSLAN 3
uThermal 2v2 Main Event
HCC Europe

Ongoing

Copa Latinoamericana 4
BSL 20 Team Wars
KCM Race Survival 2025 Season 3
BSL 21 Qualifiers
ASL Season 20
CSL Season 18: Qualifier 1
Acropolis #4 - TS1
CSL Season 18: Qualifier 2
SEL Season 2 Championship
WardiTV Summer 2025
BLAST Open Fall Qual
Esports World Cup 2025
BLAST Bounty Fall 2025
BLAST Bounty Fall Qual
IEM Cologne 2025
FISSURE Playground #1
BLAST.tv Austin Major 2025

Upcoming

CSL 2025 AUTUMN (S18)
LASL Season 20
BSL Season 21
BSL 21 Team A
Chzzk MurlocKing SC1 vs SC2 Cup #2
RSL Revival: Season 2
Maestros of the Game
EC S1
Sisters' Call Cup
IEM Chengdu 2025
PGL Masters Bucharest 2025
Thunderpick World Champ.
MESA Nomadic Masters Fall
CS Asia Championships 2025
Roobet Cup 2025
ESL Pro League S22
StarSeries Fall 2025
FISSURE Playground #2
BLAST Open Fall 2025
TLPD

1. ByuN
2. TY
3. Dark
4. Solar
5. Stats
6. Nerchio
7. sOs
8. soO
9. INnoVation
10. Elazer
1. Rain
2. Flash
3. EffOrt
4. Last
5. Bisu
6. Soulkey
7. Mini
8. Sharp
Sidebar Settings...

Advertising | Privacy Policy | Terms Of Use | Contact Us

Original banner artwork: Jim Warren
The contents of this webpage are copyright © 2025 TLnet. All Rights Reserved.