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