C报错记录

1 使用scanf/printf出错

在这里插入图片描述

2 数组越界:Run-Time Check Failure #2 - Stack around the variable ‘XXXX‘ was corrupted.

需求:
飞秋为局域网通信软件,遵循IPMSG协议,其协议格式为:

char buf[] = "1_lbt6_0#262272#54E1AD293CAD#0#0#0#4000#9:1531646672:lh:lh:32:hello world";

将IPMSG的版本号、包编号、主机名、用户名、操作码、消息 提取出来

代码:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char buf[] = "1_lbt6_0#262272#54E1AD293CAD#0#0#0#4000#9:1531646672:lh:lh:32:hello world";

	char* temp_array[6]={""};
	char* temp;
	int i = 0;

	//sscanf(buf, "%s:%ld%:%s:%s:%d:%s", version_code, &package_code, host, user, &operation_number, info);
	temp = strtok(buf, ":");
	temp_array[i++] = temp;
	while (temp)
	{
		temp = strtok(NULL, ":");
		temp_array[i++] = temp;
	}

	printf("version_code:%s\n", temp_array[0]);
	printf("package_code:%s\n", temp_array[1]);
	printf("host:%s\n", temp_array[2]);
	printf("user:%s\n", temp_array[3]);
	printf("operation_number:%s\n", temp_array[4]);
	printf("infomation:%s\n", temp_array[5]);
	return 0;
}

错误报告:

Run-Time Check Failure #2 - Stack around the variable 'temp_array' was corrupted.

在这里插入图片描述
能打印,只是运行的过程中出错了,运行时出错,一般就是由于数组越界。
问题出在while循环,可以在while中加入打印循环控制变量的语句,修改后的循环如下:

while (temp)
	{
		temp = strtok(NULL, ":");
		printf("%d\n", i);				//打印循环变量
		temp_array[i++] = temp;
	}

在这里插入图片描述
字符指针数组temp_array只有6个元素,它的下标最多只能到5,而根据打印结果,可以看到数组的下标到了6,也就是说,出现了数组越界。
究其根本,字符串buf中,冒号:只出现了5次,buf会被切6次(即strtok函数执行第6次时,返回值仍然不是NULL),第6次切完后,temp并不为空,因此未跳出while循环,导致切了第7次,此次且完后tempNULL,并且这个NULL被赋值给了temp_array[6]

即便字符串中没有冒号,strtok也是可以切的,第一次切返回字符串首地址,第二次切返回NULL

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char buf[] = "dajglgj";
	char* temp;

	temp = strtok(buf, ":");		//即便buf中没有冒号:,也是可以切的
	printf("%s\n", temp);			//输出dajglgj

	temp = strtok(NULL, ":");
	printf("%s\n", temp);			//输出(null)
	return 0;
}

输出
在这里插入图片描述

让我们回到最初的需求,现在可以将程序修改成如下形式:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>
int main() {
	char buf[] = "1_lbt6_0#262272#54E1AD293CAD#0#0#0#4000#9:1531646672:lh:lh:32:hello world";

	char* temp_array[6]={""};
	char* temp;
	int i = 0;

	//sscanf(buf, "%s:%ld%:%s:%s:%d:%s", version_code, &package_code, host, user, &operation_number, info);
	temp = strtok(buf, ":");
	temp_array[i++] = temp;
	while (temp)
	{
		temp = strtok(NULL, ":");
		if(temp) temp_array[i++] = temp;	//当temp不为NULL时才向数组赋值
	}

	printf("version_code:%s\n", temp_array[0]);
	printf("package_code:%s\n", temp_array[1]);
	printf("host:%s\n", temp_array[2]);
	printf("user:%s\n", temp_array[3]);
	printf("operation_number:%s\n", temp_array[4]);
	printf("infomation:%s\n", temp_array[5]);
	return 0;
}

在这里插入图片描述

3 写入位置XXX时发生访问冲突。

在这里插入图片描述
发生这种错误的原因,是由于给未定义的空间赋值,图中只是给dict分配了内存,但english和chinese都只是指针,指向的空间没有定义,所以会访问出错。

4 LINK2019外部符号无法解析

需求:制作一个只包含两个单词的词典

这里新建一个名为mini.c的源文件,内容如下:

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<string.h>

typedef struct _dict {
	char english[256];
	char chinese[256];
} Dict;

Dict* dict_init() {
	//hello  你好
	//world  世界
	Dict* dict = (Dict*)malloc(sizeof(Dict) * 2);
	cpystr(dict[0].english, "hello");
	cpystr(dict[0].chinese, "你好");
	cpystr(dict[1].english, "world");
	cpystr(dict[1].chinese, "世界");
	return dict;
}

void search(Dict* dict, char* english, int n)
{
	for (int i = 0; i < n; i++)
	{
		if (cmpstr(dict[i].english, english) == 0)
		{
			printf("OK!The Chinese word is:\s", dict[i].chinese);
			printf("\n");
			return ;
		}
	}
	printf("There is no %s\n", english);
}

void translate() {
	Dict* dict = dict_init();
	int ret = 0;
	char english[256];
	while (1)
	{
		printf("Please Enter the world you want to search:");
		fgets(english, strlen(english), stdin);
		english[strlen(english) - 1] = 0;
		printf("%s\n", english);
		search(dict, english, 2);
	}
	free(dict);
}

上面的代码中有三个函数,dict_init是词典初始化,search是搜索,translate是翻译

接下来再建立一个名为main.c的源文件,内容如下:

int main()
{
	translate();
	return 0;
} 

调试运行,发现有以下几个错误
在这里插入图片描述
我们自己定义的函数或者变量,在错误列表中,会在函数名前面加下划线,比如我们自己写的为dict_init,但在错误列表中为_dict_init。错误列表中,识别不了_cpystr_cmpstr,也就是说,IDE认为,我们使用了两个自定义的符号,分别为cpystrcmpstr,但却没有给出它们的定义。
可以在mini.c中查找(ctrl+F)这两个符号,以cpystr为例
在这里插入图片描述
也就是说,编译器识别不了函数cpystr,查看字符串拷贝函数,可以发现函数名为strcpy,str在前面,因此,问题找到了,即库函数名搞错。cmpstr的问题也是类似的,这里不再赘述。

将上述两个问题修改过来之后,编译能够通过,但也遇到了新的问题,当然,执行过程出错,或者执行的结果不符合预期,并不是本文讨论的内容,本文只讨论报错信息如何解除。

5 读取位置 XXX时发生访问冲突。

这种情况一般是读取未定义的空间

int** pArray_test()
{
	int* p[3];				//p的本质数组,而不是指针,数组的每个元素都是指针
	for (int i = 0; i < 3; i++)
	{
		p[i] = (int*)malloc(sizeof(int));
		*(p[i]) = i+10;
	}
	return p;
}

void test05() {
	int** p = pArray_test();
	for (int i = 0; i < 3; i++)
	{
		printf("%d\n", *(p[i]));
	}
}

在这里插入图片描述
原因:在函数pArray_test中,p是一个数组,它的内存是在栈中,函数返回时,栈中的内存被释放,但由于内存保护,*p的内容暂时被保留了起来,*p的内容,其实就是第一次调用malloc时所开辟空间的首地址,而malloc开辟的空间在堆中,因此还没释放,故可以打印出来(即控制台中的10);但test05的循环第二次执行时,内存保护失效,IDE触发异常。

6 检测到堆损坏

在这里插入图片描述

HEAP CORRUPTION DETECTED: after Normal block (#89) at 0x01596850.CRT detected that the application wrote to memory after end of heap buffer.
有两种可能:一是内存溢出,实际使用的内存大小超出了你申请的内存大小,在释放内存的时候就会发生该问题;二是释放野指针,假如某块内存被多个指针所指向,其中一个指针释放后,另一个就成为了野指针,对这个野指针释放时,就会报这种错误。

7 一元负运算符应用于无符号类型

负号用于无符号类型

printf("%d\n", -sizeof(struct Hero));

sizeof得到的结果,类型为unsigned int,前面加负号会报错
在这里插入图片描述
需要对sizeof的结果做强制类型转化

printf("%d\n", -(int)sizeof(struct Hero));	//或printf("%d\n", -(long)sizeof(struct Hero));
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值