13.C语言指针的易错点

1.指针声明和初始化

1.1未初始化(野指针)

复制代码
int *p; // 未初始化,指向随机地址
*p = 5; // 未定义行为,可能导致崩溃

修正 :初始化指针为NULL或有效地址。

1.2错误类型匹配

复制代码
int a = 10;
float *p = &a; // 类型不匹配,编译器警告

2.内存管理

内存泄漏

复制代码
int *p = (int*)malloc(sizeof(int));
// 未调用 free(p)
  • 注意:动态内存必须显式释放。

2.1内存重复释放

复制代码
free(p);
free(p); // 未定义行为(double free)

2.2悬垂指针(Dangling Pointer

复制代码
int *p = (int*)malloc(sizeof(int));
free(p);
*p = 10; // p 成为悬垂指针

3.指针运算

3.1 访问越界

复制代码
int arr[3] = {1, 2, 3};
int *p = arr;
p += 5; // 越界访问,结果不可预测

3.2 指针算术错误

复制代码
int *p = ...;
p++; // 实际移动 sizeof(int) 字节,而非 1 字节

4.数组与指针

4.1数组名不可重新赋值

复制代码
int arr[5];
arr = NULL; // 错误!数组名是常量指针

4.2数组作为函数参数退化为指针

复制代码
void func(int arr[]) { 
    // 实际等价于 int *arr 
}

5.字符串操作

5.1 未终止的字符串

复制代码
char str[3] = {'a', 'b', 'c'}; // 缺少 '\0'
printf("%s", str); // 可能输出乱码

5.2 缓冲区溢出

复制代码
char dest[5];
strcpy(dest, "HelloWorld"); // 溢出

6.函数与指针

6.1 返回局部变量指针

复制代码
int* func() {
    int a = 5;
    return &a; // a 在函数结束后被销毁
}

6.2 函数指针语法

复制代码
int (*func_ptr)(int, int); // 正确声明
int *func_ptr(int, int);   // 错误:声明了一个返回 int* 的函数

7.多级指针

7.1 错误解引用层级

复制代码
int a = 10;
int **pp = &a; // 错误:需要 int* 的地址

8. 类型转换与对齐

8.1 void指针转换

复制代码
void *p = malloc(sizeof(int));
int *q = (int*)p; // 必须显式转换

8.2 对齐问题

复制代码
char *pc = ...;
int *pi = (int*)pc; // 可能导致未对齐访问(平台相关)

9. const 修饰符

9.1 常量指针 vs 指针常量

复制代码
const int *p1; // 指向常量的指针(值不可改)
int *const p2; // 常量指针(地址不可改)

10. 空指针问题

10.1未检查 malloc 返回值

复制代码
int *p = malloc(100 * sizeof(int));
if (p == NULL) { /* 处理错误 */ }

10.2 解引用空指针

复制代码
int *p = NULL;
*p = 10; // 崩溃

11. 结构体与指针

11.1错误访问成员

复制代码
struct Point { int x; };
struct Point *p = malloc(sizeof(struct Point));
p.x = 10; // 错误:应使用 p->x

12.指针越界

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"


//指针越界
void test01() {
	char str[3] = "abc";//指针固定传入abc

	printf("str:%s ",str);
}

int main() {

	printf("main....start \n");
	test01();

	printf("main....end \n");
	return EXIT_SUCCESS;
}

从上面的指针越界来看,数组定义的长度是3,传入的是abc,abc的长度也是3,但是还有结束符\0所以这个这个属于绝对的越界行为。

13.指针叠加会不断改变指针方向

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"


void test02() {
	char* p = malloc(sizeof(char) * 64);
	
	for (int i = 0; i < 10;i++) {
		*p = i + 97;

		printf("%c", *p);
		p++;
	}
	free(p); 
}


int main() {

	printf("main....start \n");
	test02();

	printf("main....end \n");
	return EXIT_SUCCESS;
}

从上面来看p是一直++的,最后释放,存在问题,并不是从初始位释放。所以导致错误

解决方案,我们可以通过一个临时变量来操作他。

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"

void Ftest02() {
	char * p = malloc(sizeof(char) * 64);
	if (p != NULL) {
		char* pp = p;

		for (int i = 0; i < 10;i++) {
			*pp = i + 97;

			printf("%c", *pp);
			pp++;
		}
		free(p);
	} 
}


int main() {

	printf("main....start \n");
	Ftest02();

	printf("main....end \n");
	return EXIT_SUCCESS;
}

14.返回局部变量地址

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"


char* get_str()
{
	char str[] = "dabangzhu"; //栈区数据
	printf("[get_str]str = %s\n", str);
	return str;
}

int main() {

	printf("main....start \n");

	printf("main  str: %s\n",get_str());

	printf("main....end \n");
	return EXIT_SUCCESS;
}

运行结果:

15.同一块内存释放多次

复制代码
#include "stdio.h"
#include "string.h"
#include "stdlib.h"


void test01()
{
	char* p = malloc(sizeof(char)*1024);

	if (p!=NULL) {
		free(p);
	}

	//重复释放报错
	if (p != NULL) {
		free(p);
	}
}

int main() {

	printf("main....start \n");

	test01();

	printf("main....end \n");
	return EXIT_SUCCESS;
}

free()函数的功能只是告诉系统 p 指向的内存可以回收了,就是说,p 指向的内存使用权交还给系统,但是,p的值还是原来的值(野指针),p还是指向原来的内存

相关推荐
Chester_19997 小时前
CSP202203C.计算资源调度器
开发语言·数据结构·c++·蓝桥杯
EXI-小洲8 小时前
Java 操作 Word:字符串替换、图片插入、动态生成表格与API接口下载
java·开发语言·spring boot·word
会周易的程序员9 小时前
给 PLC 写一个字节码虚拟机:STVM 虚拟机架构设计
开发语言·c++·虚拟机·软plc·iec61131·stvm
机器视觉知识推荐、就业指导9 小时前
为什么老说“纯 Qt 没啥就业市场”?
开发语言·qt
telepan9 小时前
Qt 开发避坑与性能指南:如何优雅、安全地定义全局常量字符串?
开发语言·qt
m0_695251499 小时前
Qt MaintenanceTool 使用国内镜像加速下载(超详细教程)
开发语言·qt
是隼人9 小时前
buuctf-pwn xdctf2015_pwn200题解(学习过程持续更新)
c语言·学习·安全·pwn入门·ctf入门
大衛說10 小时前
《Python 从入门到精通》系列总览与学习路线
开发语言·python·学习
可乐鸡翅yeah_11 小时前
hls.js 内存泄漏实战排查,直播 M3U8 长时间播放异常定位方案
开发语言·javascript·python·django·ecmascript·m3u8·m3u8在线
2601_9622035112 小时前
Java进阶07集合(续)
java·开发语言