You should not use C/C++ if you are an irresponsible person!
0The introduction of this article was written by Meta Llama 3 70B:
C, created in 1972, has been a building block for many operating systems and applications. But its complex memory management and lack of safety nets make it prone to errors, crashes, and security risks.
Here we have 6 sample programs with a brief explanation and solution:
NULL
PointerWhen you dereference a NULL
pointer, your program will crash with a segmentation fault. This happens because the pointer is not pointing to a valid memory location, and the program is trying to access memory that it's not allowed to.
int
main()
{
int* p = NULL;
*p = 10; // BOOM!
return 0;
}
To avoid this pitfall, always check if a pointer is NULL
before dereferencing it. You can do this with a simple if statement: if (p != NULL) { *p = 10; }
. This ensures that you only try to access memory if the pointer is valid.
When you access an array element beyond its size, you're venturing into unknown territory. This can lead to unexpected behavior, crashes, or even security vulnerabilities.
int
main()
{
int arr[5];
arr[10] = 10; // Out of bounds!
return 0;
}
Make sure you stay within the bounds of the array. You can do this by using a loop that checks the array index: for (int i = 0; i < 5; i++) { arr[i] = i; }
. This ensures that you only access elements within the array's size. Alternatively, you can use a predefined constant as the size of the array and check the index to ensure it's within the valid range (0 to n-1).
When you allocate memory with malloc
, you need to free it when you're done using it. This can lead to your program consuming more memory than necessary, causing performance issues or even crashes.
#include <stdlib.h>
int
main()
{
int* p = malloc(sizeof(int));
// Forget to free(p)
return 0;
}
Always free allocated memory when you're done using it. You can do this with the free function: free(p);
. This ensures that the memory is released back to the system, preventing memory leaks.
When you use an uninitialized pointer, you're essentially pointing to a random location in memory. This can lead to undefined behavior, crashes, or even security vulnerabilities.
int
main()
{
int* p;
*p = 10; // Undefined behavior!
return 0;
}
To avoid this pitfall, always initialize pointers before using them. You can do this by setting the pointer to NULL
or assigning it a valid memory address: int* p = NULL;
or int* p = &x;
. This ensures that the pointer is pointing to a valid location in memory.
strcpy
When you use strcpy
without checking the buffer size, you can end up with a buffer overflow. This happens when the source string is larger than the destination buffer, causing the extra characters to spill over into adjacent memory locations.
#include <string.h>
int
main()
{
char* text = "Hi there! This is a relatively "
"long text...";
char copy[5];
strcpy(copy, text); // Buffer overflow!
return 0;
}
Use strncpy
or strcpy_s
instead of strcpy
. These functions allow you to specify the buffer size, preventing buffer overflows: strncpy(copy, text, 5);
. This ensures that the destination buffer is not overflowed.
malloc
When you don't check the return value of malloc
, you can end up with a NULL
pointer, leading to crashes or unexpected behavior.
#include <stdlib.h>
int
main()
{
int* p = malloc(sizeof(int));
if (p == NULL) {
// Handle the error here
}
return 0;
}
Don't forget to check the return value of malloc
for NULL
. If malloc
returns NULL
, it means that the memory allocation failed, and you should handle the error accordingly.
I tested many programming languages, but due to various reasons such as limited community support, lack of job opportunities, etc., I decided to leave them aside... Now it's the turn of C (not C++) and I wanted to share these important things, although there are many tutorials about this.
If you know another error, write it in the comments section.