From C# to C++ concept questions..

Started by
18 comments, last by jHaskell 10 years, 4 months ago

Hi,

I Know my way around the C# language fairly well and am looking to try and 'break into' doing some c++ but have a few conceptual questions to ask.

My main questions are about pointers and memory management, I believe i have researched and understood what pointers are, and how to use and manipulate them but i do not clearly understand why to use them.

C# Example:

class Program
{
static void Main(string[] args)
{
List<int> numberArray = new List<int>();
Random rnd = new Random();
for (int i = 0; i < 10000000; i++)
{
numberArray.Add(rnd.Next());
}
}
}
Now, this code should fill a dynamic array allocating memory as needed but when the variable goes out of scope it should be sent to the GC and eventually destroyed correct?
Now, if the same program were to be written in c++ using 'identical code' (ie not pointers) then that array would fill up the stack and the program should crash right?
That's why you need pointers? to send large or persistent data to the heap and not overload the stack?
Advertisement

In case we would use identical code, it would mean STL would do all the memory work; you would never get in touch.
By the way a list is something different than an array.

But internal of the STL lib, the lib use a pointer to the allocated new memory! But in case we use an array instead of a list
we have to make a different between static arrays where you know the size of an array and dynamic arrays where you
allocate new memory on the fly to write data in that array. Even an static array is nothing but less than a pointer to block in the memory.

In c++ if you allocate new memory the result will be a pointer to the first adress of the allocated memory block, Basta. What you do with that memory is up to you. In c# the gc would organize it, in c++you have to do it on your own. And that is the reason why you need pointer how otherwise could YOU manage Your memory if you don't know where it lies.

So pointers are not need it to send large data, they are needed to adress any data in the memory.

The first question you must ask is: "Why does everyone manages memory manually while there are dozens of garbage collecting mechanisms for C++?"

Usually, we manage memory by hand because automatic managing won't be sufficient.

So, we manage memory by hand to avoid automatic managing problems. Examples are the implicit overhead and some implementations that arbitrarily pauses your program to clean up.

Specialization is an even common reason for manual memory management, specialized memory pools and management implementations are way too common on game development. Usually to avoid wasting memory (duplicates), reloads (having to load an asset prematurely purged due to lack of references), runtime overhead and possible pauses. It also affects the determinism of your software, not an issue on most cases.

But managing memory manually means keeping track of everything you have allocated, and the only reference you can have is a pointer. A pointer is nothing more than an address to the start of a memory block. If the memory in the said block has been used, and won't be used again, you can simply free it so other programs (or your own) can use it. The argument against manual memory management that you can create bad code and mess up exists, but I don't like to assume bad practices.

About your code, if you create an identical, it'll probably work just the same way.

So, I must assume you're referring to static arrays?

C# Version


class Program
    {
        static void Main(string[] args)
        {
            List<int> numberArray = new List<int>();
            Random rnd = new Random();
 
            for (int i = 0; i < 10000000; i++)
            {
                numberArray.Add(rnd.Next());
            }
        }
    }

C++ Version (pointers are hidden in the vector, just like they are in the C# List)


#include <vector>
#include <cstdlib>
 
int main()
{
   //  Dynamically allocated array
   std::vector<int> numberArray;
   //  Pre-allocate enough space for the ints, to prevent additional allocations and swapping
   numberArray.reserve(10000000);
   for (int i = 0; i < 10000000; i++)
   {
      numberArray.push_back(std::rand());
   }
   return 0;
}

[edit]

See previous answers for the why. This is the equivalent C++ program.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]

I generally don't need to think much about memory management in C++, because most of the time I don't use pointers explicitly. I just use standard containers (of objects, not pointers) and local variables that clean up after themselves. I was going to post code identical to Rattrap's, so you can just look at his example: He is using the same style I just described, and memory management is not an issue.

EDIT: Sorry, to be more specific i'm not actually asking about code specifically, but why and where variables are assigned to heap verses stack.

In case we use identical code, it would mean stl would do all the memory work you would never get in touch.

By the way a list is something different than an array.

But internal of the stl lib, the lib use a pointer to the allocated new memory! But in case we use an array instead of a list
You have to make a different between static arrays where you know the size of an array and a dynamic array where you
Allocate new memory on the fly to write data in that array. Even an static array is nothing but less a pointer to field in the memory.

In c++ if you allocate new memory the result will be pointer the first adress of the allocated memory area, Basta. What you do with that memory
Is up to you. In c# the gc would organize it, in c++you have to do it on your own. And that is the reason why you need pointer how otherwise could YOU manage
Your memory if you don't know where it lies.

Sorry, not quite up with the C++ libraries, so that's a little hard to understand..

And that is the reason why you need pointer how otherwise could YOU manage

Your memory if you don't know where it lies

That's kinda core to my question, Non pointer variables get allocated to the stack and their memory is managed by going out of scope? and Pointers Allocate data to the Heap and are managed by the programmer?

C++ (im still not very good with the syntax..)


#include "stdafx.h"


void functionA(){
int a = 1; //Allocated to stack?
}
void functionB(){
int *ptrB = new int(100); //Allocated to heap?
delete ptrB;
ptrB = NULL;
}


int _tmain(int argc, _TCHAR* argv[])
{
functionA();
functionB();
return 0;
}

So, for another example/question: (again my c++ is very new)


void functionA(){
int array1 [6];
for (int i = 0; i < 6; i++)
{
array1[i] = 1;
}
}
void functionB(){


int array2[6];
int *ptrArray2 = &array2[0];


for (int i = 0; i < 6; i++)
{
*(ptrArray2+i) = 1;
}
}


int _tmain(int argc, _TCHAR* argv[])
{
functionA();
functionB();
return 0;
}
Where is the memory allocated?, Why use one function over the other?

That's why you need pointers? to send large or persistent data to the heap and not overload the stack?

If you write normal object-oriented code, C++ pointers are used just like C# object references. It's a reference to an object allocated on the heap with the new operator. And the C++ & references are more like ref arguments.

But C++ pointers support additional operations, such as adding a number to it to get the pointer to the next object in memory, or subtraction two pointers to get the "distance" or "count". With these operators you can iterate or traverse an array of objects in memory, it doesn't matter if they are on the stack or on the heap. Note that the iterators of the standard containers behave pretty much in the same way as pointers (though some of them do some automagic hocus pocus internally).

Pointers, references and memory management are very different in C+ and C#, so make sure you understand it really well. And then, as Álvaro said, understand how to use the standard containers etc. instead.

openwar - the real-time tactical war-game platform


and Pointers Allocate data to the Heap and are managed by the programmer?

Perhaps i misjudge you now but:

I think you have don't understand what a pointer is. A pointer doesn't do anything; It just point to adress in the memory.

A Pointer can't allocate anything. In c++ only the operater new or the c-function malloc ( and all his friends ) can allocate memory.

In other words a pointer hold just an adress of an allocated memory block by new or malloc which you have to handle yourself.




void functionB()
{
    int *ptrB = new int(100); //here you ask for new memory 
                              //and the first adress of the memory
                              // block will be saved as adress in the pointer ptrB

    delete ptrB; // here you free all the memory again and the pointer is invalid
    ptrB = NULL; // pointer is  valid now because you set it to NULL
}

Using new to allocate memory will typically allocate to the heap (I don't believe this is a guarantee, since the stack/heap are memory management concepts not directly defined by C++ or other languages). Plus there is placement new, which you can define where the memory is allocated (which you could point to an array on the stack).

A pointer itself is just a reference to a memory address. In the case of allocating using new (or malloc for C), you are just storing the address returned by new/malloc.

Modern C++ lets us hide away some of the nastiness of the pointer as well. You can use stl or stl like containers, which can handle the allocation and deallocation of the memory safely. You can use smart pointers to essentially wrap a raw pointer in an object that will hide the raw pointer and handle deallocation automatically when all owners are done with it/goes out of scope. This is similar to the garbage collection that you know, but you have a lot more control over when it occurs. In C#, your at the mercy of the garbage collector when memory and resources are actually released. In most cases, this is not really an issue.

"I can't believe I'm defending logic to a turing machine." - Kent Woolworth [Other Space]


and Pointers Allocate data to the Heap and are managed by the programmer?

Perhaps i misjudge you now but:

I think you have don't understand what a pointer is. A pointer doesn't do anything; It just point to adress in the memory.

A Pointer can't allocate anything. In c++ only the operater new or the c-function malloc ( and all his friends ) can allocate memory.

Sorry i should expressed that better, I understand that a pointer is just memory address, But you can use that to assign a value to the address by referencing.

I think where i have tripped up is like you say, the 'new' word actually does the memory allocation and not the declaration of the pointer/pointee

This topic is closed to new replies.

Advertisement