C 언어의 동적 메모리 할당(3)

이 장의 초점(오늘은 일반적인 동적 메모리 오류에 대해 설명합니다)

일반적인 동적 메모리 오류로 바로 이동할 수 있습니다.동적 메모리 할당 및 해당 기능이 있는 이유를 여전히 이해하지 못하는 경우 i가 있는 링크를 클릭하여 검토할 수 있으며 공식적으로 주제에 들어갈 수 있습니다.

동적 메모리 할당이 존재하는 이유

전에도 말씀드렸지만 아래 링크 참조

동적 메모리 기능 소개


동적 메모리 할당 에 대해 이미 말씀드렸습니다. (1)
동적 메모리 할당 (2)

말록

전에도 말씀드렸지만 위의 링크를 참고 하세요

무료

전에도 말씀드렸지만 위의 링크를 참고 하세요

콜록

전에도 말씀드렸지만 위의 링크를 참고 하세요

재할당

전에도 말씀드렸지만 위의 링크를 참고 하세요

일반적인 동적 메모리 오류

1**** NULL 포인터에 대한 역참조 연산

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    
    
	int* p = (int*)malloc(40);
	//这种写代码的风格是由问题的,我们需要去判断p是否为空
	*p = 20;
	return 0;
}

그 이유는 여기에서 p가 감지되지 않았기
때문에 올바른 작성 방법은 무엇입니까? 다음 코드를 참조하십시오.

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    
    
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
    
    
		return 1;
	}
	*p = 20;
	return 0;
}

이 코드는 표준 동적 메모리 개발 코드입니다.

2. 동적으로 할당된 공간에 대한 범위를 벗어난 액세스

//对动态开辟内存空间的越界访问
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<errno.h>
int main()
{
    
    
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
    
    
		printf("%s\n", strerror(errno));
		return 1;
	}
	int i = 0;
	for (i = 0; i <= 10; i++)
	{
    
    
		p[i] = i;
	}
	free(p);
	p = NULL;
	return 0;
}

3. 동적으로 할당되지 않은 메모리를 해제하려면 free를 사용하십시오.

//对非动态开辟内存空间使用free释放
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    
    
	int a = 10;//这是栈上的内存空间,属于非内存动态内存开辟的空间使用free函数释放
	int* p = &a;
	free(p);//free释放的一定是malloc/calloc/realloc所动态开辟的内存空间
	p = NULL;
	return 0;
}

4. free를 사용하여 동적으로 할당된 메모리의 일부를 해제합니다.

//使用free释放一块动态开辟内存的一部分
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    
    
	int* p = (int*)malloc(40);
	if (p == NULL)
	{
    
    
		return 1;

	}
	int i = 0;
	for (i = 0; i < 10; i++)
	{
    
    
		*p = i;
		p++;
	}
	free(p);
	p = NULL;
	return 0;
}

여기에서 p++는 마지막에 전체 배열을 생성할 것입니다. 마지막으로 p가 가리키는 공간을 해제할 때 배열의 공간(또는 일부만)을 해제할 수 없으므로 이러한 코드 작성 방식은 문제가 있습니다.

5. 동일한 동적 메모리의 여러 릴리스

//对同一块动态内存多次释放
#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
int main()
{
    
    
	int* p = (int*)malloc(40);
	free(p);//一旦释放完p之后p就成为了野指针
	p = NULL;//这里我们一旦将p置为空指针(NULL),第二个free(p)就没用了,这时候我们将p置为空指针,这是他就不是野指针了
	free(p);//会报错,编译器会说我一级帮你释放一次了你还让我帮你释放一次//对同一块空间的两次释放
	return 0;
}

다음은 첫 번째 자유 § 공간이 해제되면 p는 와일드 포인터가 됩니다. 이것은 와일드 포인터 p입니다. 하나면 충분하듯이 트리에 연결해야 하므로 NULL(빈 포인터)로 설정합니다. 그러면 p는 와일드 포인터가 아니며 두 번째 free§는 계속 실행되지 않습니다.

6. 동적으로 메모리를 열고 해제하는 것을 잊음(메모리 누수)

동적 메모리 할당(2) 에서 이 지식 포인트를 언급했습니다 . 다시 검토할 수 있습니다.

//动态开辟内存忘记释放(内存泄漏)
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
void test()
{
    
    
	int* p = (int*)malloc(100);
	int flag = 0;
	scanf_s("%d", &flag);
	if (flag == 5)
	{
    
    
		return;//...
		free(p);
		p = NULL;

	}
}


int main()
{
    
    
	test();
	//......
	return 0;
}

여기에 플래그를 입력하고 누군가가 실제로 5를 입력하고 그것에 대해 생각하고 여기에 반환하고 메인 기능을 입력하면 우리는 무료로 실행할 기회가 없으며 동적으로 열린 공간을 찾을 수 없으며 아무도 찾을 수 없습니다. 해당 공간을 확보하므로 메모리 누수가 발생합니다.

//动态开辟内存忘记释放(内存泄漏)
#define _CRT_SECURE_NO_WARNINGS 1

#include<stdio.h>
int* test()
{
    
    
	int* p = (int*)malloc(100);
	if (p == NULL)
	{
    
    
		return p;
	}
	//....
	return p;
}


int main()
{
    
    
	int* ret = test();
	//......
	return 0;
}

나는 당신의 석방을 신청했지만 당신은 그것을 해제하는 것을 잊었고 결과는 틀릴 것입니다

더 이상 사용하지 않는 동적으로 열린 공간을 해제하는 것을 잊으면 메모리 누수가 발생합니다. 기억하십시오
:
동적으로 열린 공간은 해제되어야 하며,

위의 코드는 제가 직접 작성했습니다. 이제 코드 템플릿을 알려드리겠습니다.
3.1 NULL 포인터 역참조 작동하다

void test()
{
    
    
 int *p = (int *)malloc(INT_MAX/4);
 *p = 20;//如果p的值是NULL,就会有问题
 free(p);
}

3.2 동적으로 할당된 공간에 대한 범위를 벗어난 액세스

void test()
{
    
    
 int i = 0;
 int *p = (int *)malloc(10*sizeof(int));
 if(NULL == p)
 {
    
    
 exit(EXIT_FAILURE);
 }
 for(i=0; i<=10; i++)
 {
    
    
 *(p+i) = i;//当i是10的时候越界访问
 }
 free(p);
}

3.3 free를 사용하여 비동적 메모리 해제

void test()
{
    
    
 int a = 10;
 int *p = &a;
 free(p);//ok?
}

3.4 free를 사용하여 동적으로 할당된 메모리의 일부를 해제

void test()
{
    
    
 int *p = (int *)malloc(100);
 p++;
 free(p);//p不再指向动态内存的起始位置
}

3.5 동일한 동적 메모리의 다중 릴리스

void test()
{
    
    
 int *p = (int *)malloc(100);
 free(p);
 free(p);//重复释放
}

3.6 동적으로 메모리를 열고 해제하는 것을 잊음(메모리 누수)

void test()
{
    
    
 int *p = (int *)malloc(100);
 if(NULL != p)
 {
    
    
 *p = 20;
 }
}
int main()
{
    
    
 test();
 while(1);
}

몇 가지 고전적인 필기 시험 문제

다음 블로그에서 설명할 예정이니 많은 관심 부탁드립니다.

유연한 배열

전에도 말씀드렸지만
아래 링크를 클릭하시면
플렉시블 어레이를 보실 수 있습니다.

Guess you like

Origin blog.csdn.net/fjj2397194209/article/details/131293778
Recommended