列表

详情


NC14651. Memory leak

描述

Memory leak是c/c++中常见的错误,当一个字符串比预期的长的时候,它就会不停地访问下一个内存直到长度满足预期,举个例子如下代码运行后的结果。

现在dd和cc两个人作为一个小组完成C++老师布置的学习任务,gets读取与cout输出,在正式开始写代码前当然要先写伪代码啦~那么显然dd作为程序大佬伪代码当然是由他写的,并且其中只会出现定义(char ),读取(gets),输出(cout),并且保证定义的都是如char a[n]一样的字符串。
那么cc的任务就是对这些伪代码进行手动运算,查看输出结果。
本来呢,这是个很简单的任务,读取什么输出什么,只是dd在定义时总是随手写一个数字n定义char a[n],导致代码中可能会存在内存泄漏。
那么cc作为一个严谨的好学生,就算出现了问题,她也会给出和计算机运行后一样的结果。
但是当输入量变大时,cc就发现手算太麻烦了...因为dd的字符串长度参差不齐,总是会出现问题,但是作为一个理论大佬,她并不会写这个程序,她希望你可以帮她完成这个程序,并且输出所有结果。



输入描述

多组数据,第一行输入一个整数T(<=20)表示有T组数据,
接下去多行读取中
存在四种格式:
1."cout s1" s1表示数组的名字,输出数组s1中的内容
2."gets s1 s" s1表示数组的名字,s表示读取到数组s1内的字符串内容,输入保证字符串长度<1000,并且只包含可见的ASCLL字符,并且每次gets会重写数组,并且不论读取字符串为什么,都在末尾加上"\n"(the symbol of end of a string)
3.“char s1 [s1_len],s2 [s2_len] ...;"定义类型保证为char, s1,s2为数组名称,s1_len,s2_len是长度限制。若没有出错,数组应该能储存下读取的字符串和'\0',不同数组的定义用逗号和空格分隔开,长度限制保证为正整数,且长度限制的总和≤10000.
3."return 0;" 表示一组数据的结束
每组数据中的第一行读取保证为格式3
保证输入文件小于10MB

输出描述

对于每种操作输出相应内容

示例1

输入:

3
char a[5], b[5], c[5];
gets a C++
gets b Hello, world!
gets c guys
cout a
cout b
cout c
return 0;
char a[5];
cout a
gets a 233
gets a 2333
cout a
gets a 12345
cout a
return 0;
char str1[7], str2[2], str3[5];
gets str1 welcome
gets str2 to
gets str3 Shandong
cout str1
return 0;

输出:

C++
Helloguys
guys

2333
12345
welcometoShand

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++14(g++5.4) 解法, 执行用时: 10ms, 内存消耗: 4184K, 提交时间: 2019-12-03 23:41:30

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int maxn=100005;
int l[maxn];map<string,int> mp;
string save[maxn];
int Len[maxn];
int main()
{
	//freopen("1.txt","r",stdin);
	//freopen("3.txt","w",stdout);
	int t;scanf("%d",&t);getchar();
	while(t--)
	{
		mp.clear();memset(l,0,sizeof l);
		for(int i=0;i<maxn;i++) save[i]="";
		memset(Len,0,sizeof Len);
		string s;int len,cnt=0;
		while(getline(cin,s))
		{
			if(s[0]=='r') break;
			len=s.length();string tmp="";
			if(s[0]=='c'&&s[1]=='h')
			{
				for(int i=0;i<len;i++)
				{
					if(s[i]==' ')
					{
						tmp="";continue;
					}
					if(s[i]=='[')
					{
						int ttmp=0;i++;
						while(i+1<len&&s[i]>='0'&&s[i]<='9')
						{
							ttmp*=10;ttmp+=s[i]-'0';i++;
						}
						cnt++;l[cnt]=ttmp;mp[tmp]=cnt;
						Len[cnt]=0;save[cnt]="";
					}
					else tmp+=s[i];
				}
			}
			if(s[0]=='g')
			{
				tmp="";int i=5;s+="\n";len++;
				for(i=5;i<len;i++)
				{
					if(s[i]==' ')
					{
						i++;
						break;
					}
					tmp+=s[i];
				}
				int id=mp[tmp];
				//cout<<i<<endl;
                Len[id] = len - i; 
                string ss = "";
                for (int j = 0; i < len && j < l[id]; ++i, ++j)
                    ss += s[i];
                save[id] = ss;
			}
			if(s[0]=='c'&&s[1]!='h')
			{
				tmp="";int i=5;
				for(i=5;i<len;i++) tmp+=s[i];
				int id=mp[tmp];
                string res = save[id];
                int remind = Len[id] - l[id];
                //cout<<Len[id]<<" "<<l[id]<<endl;
                for (int i = id + 1; remind > 0 && i <= cnt; ++i)
                {
                    res += save[i];
                    remind -= l[i] - Len[i]; 
                }
                int ll=res.length();
                if (res[ll-1] != '\n') res += "\n";
                cout << res;
			}
		}
	}
}

C++11(clang++ 3.9) 解法, 执行用时: 4ms, 内存消耗: 988K, 提交时间: 2020-03-18 12:24:08

#include<bits/stdc++.h>
using namespace std;
#define N 10010
int t,n;
string str;
string var[N],save[N];
int Size[N],Len[N];
map<string,int> mp;
void getName(int i,int len)
{
	string name="";
	for(;i<len;++i)
	{
		if(str[i]=='[')
		{
			++i;
			break;
		}
		name+=str[i]; 
	}
	int big=0;
	for(;i<len;++i)
	{
		if(str[i]==']') break;
		big=big*10+str[i]-'0';
	 } 
	 ++n;
	 mp[name]=n;
	 var[n]=name;
	 save[n]="";
	 Size[n]=big;
	 Len[n]=0;
}
int main()
{
	ios::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);
	cin>>t;
	getline(cin,str);
	while(t--)
	{
		n=0;
		mp.clear();
		while(1)
	    {
	    	getline(cin,str);
	    	if(str=="return 0;") break;
	    	if(str[0]=='c'&&str[1]=='h')
	    	{
	    		for(int i=0,len=str.size();i<len;++i)
	    		if(str[i]==' ')
	    		getName(i+1,len);
			}
			else if(str[0]=='g')
			{
				string name="";
				str+="\n";
				int i=0,len=str.size();
				for(;i<len;++i)
				if(str[i]==' ')
				{
					++i;
					break;
				}
				for(;i<len;++i)
				{
					if(str[i]==' ')
					{
						++i;
						break;
					}
					name+=str[i];
					
				}
				int id=mp[name];
				Len[id]=len-i;
				string s="";
				for(int j=0;i<len&&j<Size[id];++i,++j)
				s+=str[i];
				save[id]=s;
			}
			else
			{
				string name="";
				int i=0,len=str.size();
				for(;i<len;++i)
				if(str[i]==' ')
				{
					++i;
					break;
				}
				for(;i<len;++i) name+=str[i];
				int id=mp[name];
				string res=save[id];
				int remind=Len[id]-Size[id];
				for(int i=id+1;remind>0&&i<=n;++i)
				{
					res+=save[i];
					remind-=Size[i]-Len[i];
				 } 
				 if(res.end()[-1]!='\n') res+="\n";
				 cout<<res;
			}
		 } 
	}
	return 0;
}

上一题