Common memory related bugs in C language

Memory related bugs

1. Common mistakes reference

1. Classic scanf bug

scanfThe address corresponding to the variable that needs to be passed in

#include<stdio.h>
int main(void){
    
    
   int i;
   double j;
   //wrong!!!错误的写法
   scanf("%d,%ld",i,j);
   //下面是正确的写法
   scanf("%d,%ld",&i,&j);
   
}

2. The pointer is not properly initialized

It is better to assign to NULL when the correct initial value of the pointer is not known

Error example:

//计算数组a的和
int sum(int a[],int n){
    
    
    int *p;
    int sum=0;
    for(int i=0;i<n;i++){
    
    
        sum+=*p++; //指针p并未初始化
    }
}

Correct spelling: *p points to int a[]

int sum(int a[],int n){
    
    
    int *p;
    p=a;
    int sum=0;
    for(int i=0;i<n;i++){
    
    
        sum+=*p++;
    }
}

Classic error example:

#include<stdio.h>
#include<stdlib.h>
void GetMemory(char *p,int num){
    
          //p初始化为NULL,num初始化为100
    p=(char*)malloc(sizeof(char)*num); //随着栈的创建和销毁,变量p也随之消失
}                                       //整个过程只对p进行操作,并没有对str进行操作

int main(void){
    
    
    char *str=NULL;
    printf("%d\n",str);//0
    GetMemory(str,100);//这里只是把str的值NULL传过去了
    printf("%d\n",str);//0 说明str的值并没有改变
}

operation result

0
0

Correct solution 1: use the pointer of the pointer

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
void GetMemory(char **p,int num){
    
          //p初始化为str的地址,num初始化为100
    *p=(char*)malloc(sizeof(char)*num); //所以*p相当于是地址为str的变量,也就是str,对str进行赋值
}                                       //结束时p销毁,str的值已经改变

int main(void){
    
    
    char *str=NULL;
    printf("%d\n",str);//0
    GetMemory(&str,100);//这里将str的地址传过去了
    printf("%d\n",str);//6833792 说明str的值改变
    strcpy(str,"hello world!");
    puts(str);
    free(str);
}

operation result

0
6833792
hello world!

Correct solution 2: Use retrun to return the value

#include<stdio.h>
#include<stdlib.h>
#include<string.h>
char* GetMemory(int num){
    
          //num初始化为100
    char *p=(char*)malloc(sizeof(char)*num); //定义一个局部指针变量p,并对p赋值
    return p;                          //将这个值返回
}                                       

int main(void){
    
    
    char *str=NULL;
    printf("%d\n",str);//0
    str=GetMemory(100);//给str赋值为函数的返回值
    printf("%d\n",str);//
    strcpy(str,"hello world!");
    puts(str);
    free(str);
}

operation result:

0
7161472
hello world!

3. The pointer is not NULL when it is released

Wild pointer: The content pointed to by the pointer is invalid, and the pointer has not been NULL

Error example:

void relese_foo(int *p){
    
     //定义了一个指针p,并将p的值初始化为pointer的值
    free(p);//释放这块内存
    p=NULL;//将p重新赋值为空,注意pointer的值并没有发生改变
}                                  
int *pointer=(int *)malloc(sizeof(int));
int bar(){
    
    
    relese_foo(pointer);//将pointer的值传入
    return 0;
}                                                                 

Correct spelling:

void relese_foo(int *p){
    
    
    free(p);
}                                  
int *pointer=(int *)malloc(sizeof(int));
int bar(){
    
    
    relese_foo(pointer);
    pointer=NULL; //应该在此处置空
    return 0;
}

4. Don't use the return statement to return a pointer to "stack memory"

The variables in the stack will be destroyed with the return of the function.
If the pointer to the stack memory is returned, this pointer is also a wild pointer

Error example:

#include<stdio.h>
#include<string.h>
char *getString(void){
    
    
    char p[]="hello world";
    return p; //返回的这个地址内的内容已经无效了
}
int main(void){
    
    
    char *str=NULL;
    str=getString();
    puts(str);//str的内容是垃圾
}

Running result: the compiler will report a warning

ptr.c: In function 'getString':
ptr.c:6:5: warning: function returns address of local variable [enabled by default]
��a

2. Memory coverage

common one

#define array_size 100
int *a=(int *)malloc(sizeof(int)*array_size);
for(int i=0;i<=array_size;i++){
    
    
    a[i]=NULL;
}

Correct spelling: will be i<=array_sizechanged toi<array_size

common two

#define array_size 100
int *a=(int *)malloc(array_size);
for(int i=0;i<array_size;i++){
    
    
    a[i]=NULL;
}

Correct spelling:int *a=(int *)malloc(sizeof(int)*array_size);

common three

char s[8];
int i;
gets(s); //假设用户输入了123456789

No checking for maximum character size

common four

char* heapify_string(char* s){
    
    
    int len=strlen(s);
    char *new_s=(char *)malloc(len);
    strcpy(new_s,s);
    return new_s;
}

String must end with 0x00
Correct spelling:char *new_s=(char *)malloc(len+1);

common five

void dec_positive(int *a){
    
    
    *a--;//先执行a--,从右往左结合
    if(*a<0) *a=0; //此时指针a已经减一了
}

Correct writing: (*a)--;
This writing will decrement the value of the variable pointed to by a by one

Third, the second release

Error example:

void my_write(int *x){
    
    
    ...use x...
    free(x);
}
int *x=(int *)malloc(sizeof(int)*N);
my_read(x);
my_write(x);
free(x);//二次释放

Fourth, refer to the memory that has been released

Error example:

x=malloc(N*sizeof(int));
free(x);
...
y=malloc(M*sizeof(int));
for(int i;i<M;i++){
    
    
    y[i]=x[i]++;//x已经释放了
}

5. Memory leaks

The memory acquired by malloc, calloc, and realloc is not released after use. will cause a memory leak.

1. Forget to use free

    foo(){
    
    
        int *x=mallloc(N*sizeof(int));
        ...
        return;//忘记使用free
    }

2, free may not be executed

void my_function(char* msg){
    
    
    char *full_msg=(char *)malloc(strlen(msg)+100);
    strcpy(full_msg,"error was encountered");
    strcat(full_msg,msg);
    if(!display(full_msg)){
    
    
        return;//应该在这句之前加上free(full_msg);
    }
    free(full_msg);//如果上面的return执行了,那么内存不会释放;

}

3. Forget to release the malloc pointer in the structure

typedef struct
{
    
    
    char *name;
    int age;
    char *address;
    int phone;
}Person;
void my_function(){
    
    
    Person *p=(Person*)malloc(sizeof(Person))
    p->name=(char *)malloc(M);... 
    p->address=(char *)malloc(N);...
    //正确写法:应该先释放结构体内的指针
    // free(p->name);
    // free(p->address;)
    free(p);//只释放了P,结构体内的name和address并没有释放;
}

Guess you like

Origin blog.csdn.net/weixin_47138646/article/details/121462234