Visual Studio 编写程序时,常见错误及解决办法!

1、Debug Assertion Failed

(1) 定义指针char *name,但是没有将指针指向有效的地址空间:

示例:

#define _CRT_SECURE_NO_WARNINGS
#include 

int main(void)
{
        char *name;
	//char *name = NULL;
	//char array[100] = {0};
	//name = array;
	printf("What's your name:");
	scanf("%s", name);
	printf("Your name is %s\n", name);

	return 0;
}

(2)  内存泄漏:如果申请的动态内存没有及时释放会怎样?

  •  隐式内存泄漏:即用完内存块没有及时使用free函数释放
  •  丢失内存块地址:

示例:(针对丢失内存块地址)

#include 
#include 
 
int main()
{
	int *ptr;
	int num = 123;
 
	ptr = (int *)malloc(sizeof(int));
	if (ptr == NULL)
	{
		printf("分配内存失败!\n");
		exit(1);
	}
 
	printf("请输入一个整数:");
	scanf("%d", ptr);
 
	printf("你输入的整数是:%d\n", *ptr);
 
	ptr = #
	printf("你输入的整数是:%d\n", *ptr);
 
	free(ptr); //此处?
 
	return 0;
}

如果,程序中,free(ptr),会报错:

是因为:指针ptr已经指向了局部变量num,用free(ptr),去释放一个局部变量!当然,malloc申请的动态内存的地址丢掉了,也就丢失了内存……

Visual Studio 编写程序时,常见错误及解决办法!_第1张图片

2、error C2440: “=”: 无法从“const char [2]”转换为“char”

Visual Studio中,后缀为.cpp时,报错;

Visual Studio 编写程序时,常见错误及解决办法!_第2张图片

只需修改为:

	char *string1 = "I love FishC.com";
	char *string2 = "very much";
修改为:
	const char *string1 = "I love FishC.com";
	const char *string2 = "very much";

Visual Studio中,后缀为.c时,不会报错

示例代码:

#define _CRT_SECURE_NO_WARNINGS
#include 
#include 

int global_var1;
int global_var2;
static int file_static_var1;
static int file_static_var2;

void func1(int func1_param1, int func1_param2)
{
	static int func1_static_var1;
	static int func1_static_var2;

	// 输出行参的地址
	printf("addr of func1_param1: %010p\n", &func1_param1);
	printf("addr of func1_param2: %010p\n", &func1_param2);

	// 输出静态局部变量的地址
	printf("addr of func1_static_var1: %010p\n", &func1_static_var1);
	printf("addr of func1_static_var2: %010p\n", &func1_static_var2);
}

void func2(const int func2_const_param1, const int func2_const_param2)
{
	int func2_var1;
	int func2_var2;

	// 输出const参数的地址
	printf("addr of func2_const_param1: %010p\n", &func2_const_param1);
	printf("addr of func2_const_param2: %010p\n", &func2_const_param2);

	// 输出局部变量的地址
	printf("addr of func2_var1: %010p\n", &func2_var1);
	printf("addr of func2_var2: %010p\n", &func2_var2);
}

int main(void)
{
	char *string1 = "I love FishC.com";
	char *string2 = "very much";

	// 输出函数的地址
	printf("addr of func1: %010p\n", func1);
	printf("addr of func2: %010p\n", func2);

	// 输出字符串常量的地址
	printf("addr of string1: %010p\n", string1);
	printf("addr of string2: %010p\n", string2);

	// 输出全局变量的地址
	printf("addr of global_var1: %010p\n", &global_var1);
	printf("addr of global_var2: %010p\n", &global_var2);

	// 输出文件内的static变量的地址
	printf("addr of file_static_var1: %010p\n", &file_static_var1);
	printf("addr of file_static_var2: %010p\n", &file_static_var2);

	// 输出函数内局部变量的地址
	func1(1, 2);
	func2(3, 4);

	return 0;
}

3、寄存器变量,不能读取地址

(1)源文件后缀为.c时,会报错:

Visual Studio 编写程序时,常见错误及解决办法!_第3张图片

即:将变量声明为寄存器变量,那么就没有办法通过取址运算符获得该变量的地址

(2)源文件后缀为.cpp时,不会报错:

Visual Studio 编写程序时,常见错误及解决办法!_第4张图片

4、C2099    初始值设定项不是常量   

代码: .c报错,.cpp不会报错;

#include 
#include 

int main(void)
{
	static int *pi = (int *)malloc(sizeof(int));

	*pi = 520;
	printf("*pi = %d\n", *pi);

	return 0;
}

解决办法:

静态分配的变量,都是在编译时刻就决定了地址和初始值的来源

malloc是个运行时刻的函数

上面程序如果编译会报错,这是因为初始化静态变量时不能调用函数。static 声明的变量在程序运行过程中是始终存在的,通常在 main 函数运行之前就完成了初始化过程。*4='q?"KR
,D:NB3H' q2`?Koh9.;(
但 malloc 函数的调用是在 main 函数之后进行的,所以从概念上来说,static 声明的变量不可能通过调用库函数来进行初始化。同样的道理,这个规则对于全局变量来讲也是一样的!Li?Q>8o7Y#
!DUX@9V~ I>f+Ase}Wj`vlgKYa4EJ8
对于静态变量来说,可以通过在后面用一个单独的语句给变量分配内存来避免这个问题:n

……
        static int *pi;
        pi = (int *)malloc(sizeof(int));
……

5、C1071    在注释中遇到意外的文件结束    

 大块代码的注释一般用 “/* 代码*/”;其中 ”/*“ 和 “*/”作为一个整体使用,如果分割开,就会报错!

Visual Studio 编写程序时,常见错误及解决办法!_第5张图片

备注:代码的另外一种注释方式为:条件编译!

6、Run-Time Check Failure #2 - Stack around the variable 'a' was corrupted

Visual Studio 编写程序时,常见错误及解决办法!_第6张图片

这个报错字面意思是:定义的变量xxx附近的内存被破坏了!

一般情况下,第一反应就是堆栈溢出、内存访问越界 …没错,这是第一个解决方案
【解决方案】如果提示中的变量是指针类型变量,则大概率的就是数组访问越界,需要反复检查数组下标访问的合法性

如果提示中的变量并不是指针,而是普通局部变量,在检查代码逻辑无误后,此时问题的解决方案如下(具体出错原因不太清楚,我认为是VS编译器的优化问题)
【解决方案】:
方法一:可以将该局部变量设置为全局变量即可
方法二:可以在“ 项目 ---- 属性 ---- 配置属性 ---- C/C++ ---- 代码生成 ---- 基本运行时检查:”设置为默认值,点击应用,确定后即可!

参考链接:https://blog.csdn.net/qq_43746320/article/details/104603363

6、C4700    使用了未初始化的局部变量“b1”   

示例代码:

将结构体变量初始化为0,就可以!

struct Book b1 , b2 ; 改为:struct Book b1 = { 0 }, b2 = {0};

#include 

struct Date
{
	int year;
	int month;
	int day;
};

struct Book
{
	char title[128];
	char author[40];
	float price;
	struct Date date;
	char publisher[40];
};

struct Book getInput(struct Book book);
void printBook(struct Book book);

struct Book getInput(struct Book book)
{
	printf("请输入书名:");
	scanf("%s", book.title);
	printf("请输入作者:");
	scanf("%s", book.author);
	printf("请输入售价:");
	scanf("%f", &book.price);
	printf("请输入出版日期:");
	scanf("%d-%d-%d", &book.date.year, &book.date.month, &book.date.day);
	printf("请输入出版社:");
	scanf("%s", book.publisher);

	return book;
}

void printBook(struct Book book)
{
	printf("书名:%s\n", book.title);
	printf("作者:%s\n", book.author);
	printf("售价:%.2f\n", book.price);
	printf("出版日期:%d-%d-%d\n", book.date.year, book.date.month, book.date.day);
	printf("出版社:%s\n", book.publisher);
}

int main(void)
{
	//struct Book b1 = { 0 }, b2 = {0};
	struct Book b1 , b2 ;

	printf("请录入第一本书的信息...\n");
	b1 = getInput(b1);
	putchar('\n');
	printf("请录入第二本书的信息...\n");
	b2 = getInput(b2);

	printf("\n\n录入完毕,现在开始打印验证...\n\n");

	printf("打印第一本书的信息...\n");
	printBook(b1);
	putchar('\n');
	printf("打印第二本书的信息...\n");
	printBook(b2);

	return 0;
}

从上代码可以看出,main中调用子函数,通过值传递,将结构体变量b1 b2传递到子函数;

如果修改子函数代码,通过子函数的结构体指针对main中的b1、b2进行赋值、修改,则不会报错:示例如下:

#include 

struct Date
{
	int year;
	int month;
	int day;
};
struct Book
{
	char title[128];
	char author[40];
	float price;
	struct Date date;
	char publisher[40];
};

void getInput(struct Book *book);
void printBook(struct Book *book);

void getInput(struct Book *book)
{
	printf("请输入书名:");
	scanf("%s", book->title);
	printf("请输入作者:");
	scanf("%s", book->author);
	printf("请输入售价:");
	scanf("%f", &book->price);
	printf("请输入出版日期:");
	scanf("%d-%d-%d", &book->date.year, &book->date.month, &book->date.day);
	printf("请输入出版社:");
	scanf("%s", book->publisher);
}

void printBook(struct Book *book)
{
	printf("书名:%s\n", book->title);
	printf("作者:%s\n", book->author);
	printf("售价:%.2f\n", book->price);
	printf("出版日期:%d-%d-%d\n", book->date.year, book->date.month, book->date.day);
	printf("出版社:%s\n", book->publisher);
}

int main(void)
{
	struct Book b1, b2;

	printf("请录入第一本书的信息...\n");
	getInput(&b1);
	putchar('\n');
	printf("请录入第二本书的信息...\n");
	getInput(&b2);

	printf("\n\n录入完毕,现在开始打印验证...\n\n");

	printf("打印第一本书的信息...\n");
	printBook(&b1);
	putchar('\n');
	printf("打印第二本书的信息...\n");
	printBook(&b2);

	return 0;
}

总结:

传递结构体(或其他int 、char等数据类型)变量到子函数中,需要初始化;(结构体变量作为参数传递

传递指向结构体变量的指针,不需要对数据初始化;

7、  错误    C2040    “sol”:“int”与“sol_t *”的间接寻址级别不同   

详细解释:C语言关于出现错误代码C2040 间接寻址级别不同的问题

粘贴下来的图:

Visual Studio 编写程序时,常见错误及解决办法!_第7张图片

 

 

 

 

 

 

 

 

你可能感兴趣的:(C知识点)