开发者

Why C/C++ have memory issue?

开发者 https://www.devze.com 2023-01-02 21:48 出处:网络
I have readlots 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++ an

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.


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);
}


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.


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 :)


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.


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.


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.


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.


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.


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++.

0

精彩评论

暂无评论...
验证码 换一张
取 消