Jump to content
MrGrj

How to avoid errors in your C and C++ Code

Recommended Posts

  • Active Members

Today we are going to go through effective techniques to avoid errors in your C and C++ programming sessions.

Errors in programming can affect the stability and functionality of the application, we are going to run through how to avoid that.

Memory errors can be broadly classified into Heap Memory Errors and Stack Memory Errors. Some of the challenging memory errors are:

  • Invalid Memory Access in heap and stack
  • Memory leak
  • Mismatched Allocation/Deallocation
  • Missing Allocation
  • Uninitialized Memory Access in heap and stack
  • Cross Stack Access

Invalid Memory Access

This error occurs when a read or write instruction references unallocated or deallocated memory.


char *pStr = (char*) malloc(25);
free(pStr);
strcpy(pStr, .parallel programming.); // Invalid write to deallocated memory in heap

Memory leaks

Memory leaks occur when memory is allocated but not released. If such leaks happen often enough and frequently enough, the leaks will eventually cause the application to run out of memory resulting in a premature termination (gracefully or as a crash).

char *pStr = (char*) malloc(512);
return;

Mismatched Allocation/Deallocation

This error occurs when a deallocation is attempted with a function that is not the logical counterpart of the allocation function used.

char *s = (char*) malloc(5); 
delete s;

To avoid mismatched allocation/deallocation, ensure that the right deallocator is called. In C++, new[] is used for memory allocation and delete[] for freeing up. In C, malloc(), calloc() and realloc() functions are used for allocating memory while the free() function is used for freeing up allocated memory. Similarly, there are APIs in Windows programming to allocate and free memory.

Missing allocation

This error occurs when freeing memory which has already been freed. This is also called “repeated free” or “double free”.

Example:

char* pStr = (char*) malloc(20); 
free(pStr);
free(pStr); // results in an invalid deallocation

Uninitialized Memory Access

This type of memory error will occur when an uninitialized variable is read in your application.

char *pStr = (char*) malloc(512);
char c = pStr[0]; // the contents of pStr were not initialized

void func()
{
int a;
int b = a * 4; // uninitialized read of variable a
}

To avoid this type of memory error, always initialize variables before using them.

Cross Stack Access

This occurs when a thread accesses stack memory of a different thread.

main()
{
int *p;
-------
CreateThread(., thread #1, .); // Stack Owned
CreateThread(., thread #2, .);
-------
}

Thread #1

{ 
int q[1024];
p = q;
q[0] = 1;
}

Thread #2

{ 
*p = 2; // Stack Cross Accessed
}

One of the easiest ways to avoid this error is to avoid saving stack addresses to global variables.

Using tools to find memory errors

There are many memory error checkers available on the market; I used Intel Parallel Inspector to find memory errors. This is an easy and comprehensive tool to pinpoint memory errors in both sequential and multithreaded applications.

Intel Parallel Inspector integrates into Visual Studio. Parallel Inspector uses dynamic instrumentation that requires no special builds or compilers. Not all memory checkers available in the market are capable of performing analysis of threaded applications. As shown below, Parallel Inspector finds all types of memory errors and displays source, module and source line number with state of error (fixed/not fixed).

One important feature of this tool is that it allows end users to control the depth of analysis. The greater the depth of analysis, the longer the analysis takes and the more memory it uses.

  • 2x-20x – analysis finds memory leaks
  • 10x-40x – analysis identifies the existence of a problem
  • 20x-80x – analysis provides root cause information to fix problems and enhanced dangling pointer check
  • 40x-160x – provides the most comprehensive level of problem (including system libraries check)

If a memory error is either not relevant or not going to be fixed, there is an option to suppress the error. Select suppressions from the configuration settings and choose the appropriate option.

Link to comment
Share on other sites

Nah, cea mai buna alternativa este sa folosesti smart point-eri:

c++ - What is a smart pointer and when should I use one? - Stack Overflow

Nimerni nu mai foloseste malloc()/free(), new[],delete(), cel putin in proiectele de mare anvergura(spre exemplu motoare de jocuri) in prezent. Cele mai "periculoase" erori sunt cele care provin dintr-un design precar al aplicatiilor(greu de extins, inteles, optimizat, cod scris intr-un mod nelizibil). Cei care sunt interesati ar putea citi:

"Code Complete 2":

https://5d0c00d0babedc9d7abd62f30361d865b480e494.googledrive.com/host/0B4m99Zn8K7eGZzlUTFZCX20yVE0/programming/Code%20Complete.2.Edition.pdf

"Why Programs Fail":

http://read.pudn.com/downloads154/doc/fileformat/678870/Why_Programs_Fail_-_A_Guide_to_Systematic_Debugging.pdf

"The Mythical Man Month:"

http://is.muni.cz/www/208322/The.Mythical.Man.Month.F.Brooks.pdf?lang=en

Link to comment
Share on other sites

  • Active Members

@Ganav, ma refer la proiectele uzuale / clasice :P

Evident ca in ceea ce priveste proiecte de anvergura, exista alte metodologii mult mai bune decat ceea ce am prezentat eu.

Nu poti cere unui beginner sa invete despre smart pointers daca el habar nu are care e diferenta dintre calloc() si malloc()

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.



×
×
  • Create New...