views:

502

answers:

9

I have read lots of programmers saying and writing when programming in C/C++ there are lots of issue related to memory. I am planning to learn to program in C/C++. I have beginner knowledge of C/C++ and I want to see some short sample why C/C++ can have issues with memory management. Please Provide some samples.

+3  A: 

The reason that this is commonly cited as something that is different in C/C++ is that many modern languages perform memory management and garbage collection. In C/C++ this is not the case (for better or for worse). You need to manually allocate and deallocate memory, and failing to do so correctly results in a memory leak that would not be possible in a language that performs memory management for you.

VeeArr
When the programmer is allocating and deallocating the memory it why he needs a garbage collection?
LinuxNewbie
@LinuxNewbie: He doesn't! C++ does not do automatic garbage collection. Have a look here: http://en.wikipedia.org/wiki/Garbage_collection_%28computer_science%29
nico
"You need to manually allocate and deallocate memory" -> Not necessarily. There are tools that reduce the need to deallocate memory manually, for example `boost::shared_ptr<T>`.
FredOverflow
@FredOverflow: It is done manually- just the manual function is written by someone else and called by the compiler :P
DeadMG
+3  A: 

One of the common memory management problems in C and C++ is related to the lack of bounds checking on arrays. Unlike Java (for example), C and C++ do not check to make sure that the array index falls within the actual array bounds. Because of this, it is easy to accidentally overwrite memory. For example (C++):

char *a = new char[10];
a[12] = 'x';

There will be no compile or runtime error associated with the above code, except that your code will overwrite memory that shouldn't be.

Greg Hewgill
Thanks for this sample.
LinuxNewbie
"There will be no compile or runtime error associated with the above code" -> you can use [smarter memory routines](http://stackoverflow.com/questions/2835416/critique-my-non-intrusive-heap-debugger) to detect buffer overflows at runtime ;)
FredOverflow
Many compilers and operating systems will issue errors for this at runtime, such as AV on Windows and debug assertions in the CRT for Visual Studio.
DeadMG
@FredOverflow @DeadMG: True, but both those solutions detect the error *later* than the time the memory is actually overwritten. There are more intrusive instrumentation techniques (eg. valgrind) that can detect the error sooner.
Greg Hewgill
but does this cause memory leaks? I believe the problem is you do not call delete... rather at most it would be a "segmentation fault" problem, but not a memory leak problem.
ShinTakezou
+6  A: 

Basically, in these languages, you have to manually request every bit of memory that is not a local variable known at compile time, and you have to manually release it when you don't need it anymore. The are libraries (so-called smart pointers) that can automate this process to some degree, but they are not applicable everywhere. Furthermore, there are absolutely no limits to how you can (try to) access memory via pointer arithmetics.

Manual memory management can lead to a number of bugs:

  • If you forget to release some memory, you have a memory leak
  • If you use more memory than you've requested for a given pointer, you have a buffer overrun.
  • If you release memory and keep using a "dangling pointer" to it, you have undefined behaviour (usually the program crashes)
  • If you miscalculate your pointer arithmetics, you have a crash, or corrupted data

And many of these problems are very hard to diagnose and debug.

Michael Borgwardt
Can you show me how to request a bit of memory? malloc takes a whole number of bytes!
Pete Kirkham
@Pete: well, the fact that you get them in bunches of 8 does not contradict my statement that you have to request them manually, does it?
Michael Borgwardt
So I've visited *every* continent because I've visited (over) 1/8 of them?
Pete Kirkham
+14  A: 

There are many ways you can corrupt or leak memory in C or C++. These errors are some of the most difficult to diagnose, because they are often not easily reproducible.

For example, it is simple to fail to free memory you have allocated. For example, this will do a "double free", trying to free a twice and failing to free b:

char *a = malloc(128*sizeof(char));
char *b = malloc(128*sizeof(char));
b = a;
free(a);
free(b); // will not free the pointer to the original allocated memory.

An example buffer overrun, which corrupts arbitrary memory follows. It is a buffer overrun because you do not know how long str is. If it is longer than 256 bytes, then it will write those bytes somewhere in memory, possible overwriting your code, possibly not.

void somefunc(char *str) {
    char buff[256];
    strcpy(buff, str);
}
fmark
Thanks, That is a good sample. I will keep this in mind.
LinuxNewbie
+1 for C OR C++!
AndrejaKo
I've got to restrain myself to edit away the C++ of this answer, given it's pure C code inside...
Matthieu M.
Strcpy? owch. Use std::string and problemo solvo.
DeadMG
There's no std::string in C!
fmark
@fmark: Shouldn't it be `"trying to free a twice and failing to free b"`?
Lazer
@Lazer - yep! I was just trying to demonstrate why memory management in C is hard by making a mistake in the example mistake.
fmark
+5  A: 

I am planning to learn to program in C/C++

What exactly do you mean by that? Do you want to learn to program in C, or do you want to learn to program in C++? I would not recommend learning both languages at once.

From a user's perspective, memory management in C++ is a lot easier than in C, because most of it is encapsulated by classes, for example std::vector<T>. From a conceptual perspective, C's memory management is arguable a lot simpler. Basically, there's just malloc and free :)

FredOverflow
Actually I have an idea of a small utility, so I was thinking to do that using C (not C++ I think C++ is little bit far from me now considering the OOP concepts and design). Then I am planning to convert that utility into C++ which will give me opportunity to learn the C++. I am planning (hoping) to finish my utility in 9~11 months.
LinuxNewbie
@Linux: Learning C as a stepping stone to C++ is *not* recommended by [Stroustrup](http://www.research.att.com/~bs/bs_faq.html#prerequisite).
FredOverflow
@LinuxNewbie: C++ is hugely easier than C, because those OOP concepts will save you from doing an absolute shitload of work.
DeadMG
+2  A: 

When new is used to gain a block of memory the size reserved by the operating system may be bigger than your request, but never smaller. Because of this and the fact that delete doesn't immediately return the memory to the operating system, when you inspect the whole memory that your program is using you may be made to believe that your application has serious memory leaks. So inspecting the number of bytes the whole program is using should not be used as a way of detecting memory errors. Only if the memory manager indicates a large and continuous growth of memory used should you suspect memory leaks.

Rupeshit
+5  A: 

I can honestly say that I have no "issues" with memory allocation when programming in C++. The last time I had a memory leak was over 10 years ago, and was due to blind stupidity on my part. If you write code using RAII, standard library containers and a small modicum of common sense, the problem really does not exist.

anon
+1  A: 

One thing not mentioned so far is performance and why you want to manually manage memory. Managing memory is hard to do accurately especially as a program becomes more complex(especially when you use threads and when the lifetime of pieces of memory becomes complex(ie when it gets hard when its hard to tell exactly when you don't need a piece of information)) even with powerful modern programing tools like valgrind.

So why would you want to manually manage memory,a few reasons: --To understand how it works/to --To implement garbage collection/automatic memory management you need to manually --With some lower level things such as a kernel you need the flexibility manual control of memory can give. --Most importantly if you do manual memory management right you can gain a large speedup/lower memory overhead(better performance), an associated problem with garbage collection(although its getting better as better garbage collectors such as the hotspot jvm one are written) is that you can't control memory management so it hard to do stuff with real time stuff(guaranteeing deadlines for certain objectives like car brakes and pacemakers, try special real time gc) and programs that interact with users might freeze up for a little bit or lag(this would suck for a game).

A lot of "Modern C++" (it has been said that C++ can be thought of as multiple languages depending on how you use it) as opposed to c with classes(or x and y C++ feature) use a compromise by frequently using simple optional gc/automatic memory management(note that optional gc can be worse at memory management then mandatory because when its mandatory its a simpler system) features and and some manual memory management. Depending on how you do this it can have some advantages and disadvantages of using gc and doing manual memory management. Optional GC is also available with some C libraries but its less common with c then c++.

Roman A. Taycher
+1 Having skills in manual memory work really helps you understand how the GC systems work..and when you'd better do it yourself.
Rusty
+2  A: 

It is obvious you have to release that memory which is no longer in use or not use in future, but you have to determine at the begining of the programme , the memory requirement is static or varied when it execute. If it dynamic you take enough memory for your program work that time may be your program consume extra memory.

so you have to release that memory which not in use and create that time when it is needed. just like

struct student
{
 char name[20];
 int roll;
 float marks;
}s[100];

Here I suppose 100 student in class. Student may be more than 100 or less 100. If more than 100 then your programme will lose information or less 100 then programme will run but waste of memory, it can be big.

so we are usually create a record dynamically at the time of execution. just like

struct student *s;

s=(struct student *)malloc(sizeof(struct student));

scanf("%s %d %f",s->name,s->roll,s->marks);

if not in use then delete it form momery space.

free(s);

That is good manner for programming, if you not remove from memory then at one time it can full your memory stack and it can be hang.

R.K.Rahu