其他分享
首页 > 其他分享> > C--开辟输入n行3列二维数组的bug

C--开辟输入n行3列二维数组的bug

作者:互联网

今天在刷题的时候遇到里一个bug,试了很多办法都没有解决,最后用malloc开辟动态内存解决了这个问题,期间遇到了各种bug,最后来总结一下我解决问题的过程。


先把题目摆在这里

若有非零整数A、B、C,将其组成两个等式(A@B)#C = 24、A@(B#C) = 24,其中@和#为运算符号’+’、’-’、’*’、’/’、’%'之一,
同一符号可选择一次或多次,如果这两个等式至少有一个成立,则输出YES,否则输出NO。
输入:
第一行输入正整数N,表示有N组数据。(N<1000)
其后N行每行输入非零整数A、B、C(-1e5 <= A、B、C <= 1e5)
输出:
如果两个等式至少有一个成立,则输出YES,否则输出NO,每组数据的输出占一行。
样例输入 :
3
4 1 6
3 4 5
6 3 12
样例输出 :
YES NO YES
(注意,在该题中整数 / 整数,取结果的整数部分,例如1 / 4 = 0)

如何输入n行3列的数据呢?
我先是这样写的代码

int n=0;
scanf("%d", &n);
int arr[][3] = { 0 };
for (int i = 0; i < 3; i++)
{
	arr[i] = (char*)malloc(sizeof(int)*3);//动态开辟列内存
}

这样我一运行傻了,我照题目的用例输入数据,输完3行后程序还在继续,我输了5行程序才停止,于是我调试了一下,发现
在这里插入图片描述
?????,为啥我的n值改变了,变成了我最后输入的一个数据5,所以循环一直执行下去了,直到我输入了5行。

随后我想到可能是n所在内存被5覆盖掉了,于是我又去内存中找找原因,果然!!!
在这里插入图片描述
看!我这里的n本来是3,直到我输完了第二行,n值所在的内存被5也就是arr[1][2]所覆盖掉了。于是我意识到了,这个二维数组在我没有定义行的时候,它默认只开辟了一行数据空间,也就是3个int类型空间的大小,这里我画个图就清楚了。
在这里插入图片描述
既然变量n和开辟的二维数组离的这么近,我何不让两个变量不在一块内存中,于是我就想到了把n作为全局变量写在程序中,因为全局变量开辟是在内存中的全局存储区,而局部变量的开辟是在内存中的栈上。这样不在一块开辟,何谈覆盖不覆盖而言!!!

于是我就这样干的,运行程序,竟然又是一个错误代码,我这个思路没有错啊,怎么回事。
在这里插入图片描述
我的天,这是什么,
Run-Time check Failure#2 - stack around the variable “arr” wascorrupted.
翻译过来是:运行时检查失败#2-变量“arr”周围的堆栈已损坏。


网上查了一下,这次的问题是二维数组开辟的问题
默认只开了3个(int)型的空间,好家伙,我直接输了9个,直接越界,这个问题有时候会报错有时候不会,按理来说,哨兵位就是保护栈的让变量的内存之间,贸然给哨兵位赋值或者一直访问没有开辟的内存,就有可能出现这个报错!!!


没得办法,我只好老老实实在堆开辟一块动态内存,用来存放我的二维数组。
用malloc语句
因为是二维数组,我只好开辟1000个(int*)的内存作为行(题目说不能不能超过1000行)

arr = (int**)malloc(1000 * sizeof(int*));

然后for循环每个行,在每行中开辟3个(int)的空间作为列

for (int i = 0; i < 3; i++)
{
arr[i] = (char*)malloc(sizeof(int) * 3);//动态开辟列内存
}

这样就完美开辟出了一块内存空间存放我的n行3列数组。
(注):不要忘了free掉空间和把指针置为NULL呦!!!


之后的算法很简单,我把源码粘在博客上供小伙伴们参考

#define _CRT_SECURE_NO_WARNINGS 1
#include<stdio.h>
#include<stdlib.h>

//若有非零整数A、B、C,将其组成两个等式(A@B)#C = 24、A@(B#C) = 24,其中@和#为运算符号'+'、'-'、"*、'/'、'%'之一,
//同一符号可选择一次或多次,如果这两个等式至少有一个成立,则输出YES,否则输出NO。
//输入:
//第一行输入正整数N,表示有N组数据。(N<1000)
//其后N行每行输入非零整数A、B、C(-1e5 <= A、B、C <= 1e5)
//输出 :
//如果两个等式至少有一个成立,则输出YES,否则输出NO,每组数据的输出占一行。
//样例输入 :
//3
//4 1 6
//3 4 5
//6 3 12
//样例输出 :
//YES
//NO
//YES
//(注意,在该题中整数 / 整数,取结果的整数部分,例如1 / 4 = 0)

int Operation(int a, int b,int input)
{
	switch (input)
	{
	case 1:
		return a + b;
		break;
	case 2:
		return a - b;
		break;
	case 3:
		return a*b;
		break;
	case 4:
		return a / b;
		break;
	case 5:
		return a%b;
		break;
	default:
		break;
	}
	return 0;
}

int main()
{
	int n=0;
	scanf("%d", &n);
	int **arr = NULL;
	//动态开辟行内存
	arr = (int**)malloc(1000*sizeof(int*));
	for (int i = 0; i < 3; i++)
	{
		//动态开辟列内存
		arr[i] = (char*)malloc(sizeof(int)*3);
	}
	for (int i = 0; i < n; i++)
	{
		scanf("%d %d %d", &arr[i][0], &arr[i][1],&arr[i][2]);
	}
	int num1 = 0;
	int num2 = 0;
	int input1 = 0;
	for (int i = 0; i < n; i++)
	{
		for (input1 = 1; input1 < 6; input1++)
		{
			int a = Operation(arr[i][0], arr[i][1], input1);
			int b = Operation(arr[i][1], arr[i][2], input1);
			for (int input2 = 1; input2 < 6; input2++)
			{
				num1 = Operation(a, arr[i][2], input2);
				num2 = Operation(b, arr[i][0], input2);

				if (num1 == 24 || num2 == 24)
				{
					printf("Yes\n");
					break;
				}
			}	
			if (num1 == 24 || num2 == 24)
			{
				break;
			}
		}
		if (input1 == 6)
		{
			printf("No\n");
		}
	}
	free(arr);
	arr = NULL;
	return 0;
}

标签:24,arr,--,开辟,break,int,二维,内存,bug
来源: https://blog.csdn.net/starry1441/article/details/110450894