out of memory

提供: MonoBook
ナビゲーションに移動 検索に移動

out of memoryとは、黒歴史であるLSI C-86 試食版わがままの一つである。

概要

詳細な発生条件は不明だが、ソースコードの長さが関係している可能性がある。

再現例

ここに示した方法は、環境依存かもしれない。

1.LSI C-86 試食版を入手し、初期設定を行う
LSI C-86 試食版はVectorから入手できる。

2.次のコードをtxedit.cとして適当なフォルダに保存する

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

long strnum(char*);

int main(void) {
	FILE *file;
	char* naiyou;
	char* edit;
	char cmd[10000];
	char content[10000];
	char filename[10000];
	long line;
	size_t size;
	long nowline;
	char* now;
	char command[10000];
	naiyou=calloc(1,1);
	while(1) {
		printf("command>");
		fgets(command,10000,stdin);
		now=strpbrk(command," ");
		memset(content,0,10000);
		line=0;
		if(now==NULL) {
			now=strpbrk(command,"\n");
			*now=0;
			strcpy(cmd,command);
		} else {
			memcpy(cmd,command,now-command);
			cmd[now-command]=0;
			command[strlen(command)-1]=0;
			if(*(now+1)=='\"') {
				edit=strpbrk(now+2,"\"");
				if(edit==NULL)edit=command+strlen(command)-1; else {
					if(*(edit+1)==32)line=atol(edit+2);
				}
				memcpy(content,now+2,edit-now-2);
			} else {
				edit=strpbrk(now+1," ");
				if(edit==NULL)edit=command+strlen(command); else {
					line=atol(edit+1);
				}
				memcpy(content,now+1,edit-now-1);
			}
		}
		switch(strnum(cmd)) {
		case 93:/*new*/
			if(naiyou!=NULL)free(naiyou);
			naiyou=calloc(1,1);
			printf("成功\n");
			break;
		case 118:/*open*/
			file=fopen(content,"r");
			if(file==NULL) {
				printf("error:ファイルオープンに失敗\n");
			} else {
				strcpy(filename,content);
				fseek(file,0,SEEK_END);
				size=ftell(file);
				if(naiyou!=NULL)free(naiyou);
				naiyou=calloc(size+1,1);
				fseek(file,0,SEEK_SET);
				fread(naiyou,size,1,file);
				fclose(file);
				printf("成功\n");
			}
			break;
		case 107:/*save*/
			file=fopen(content,"w");
			if(file==NULL) {
				printf("error:ファイルオープンに失敗\n");
			} else {
				strcpy(filename,content);
				fwrite(naiyou,strlen(naiyou),1,file);
				fclose(file);
				printf("成功\n");
			}
			break;
#ifdef CAUSE_OOM
		case 199:/*update*/
			file=fopen(filename,"w");
			if(file==NULL) {
				printf("error:ファイルオープンに失敗\n");
			} else {
				fwrite(naiyou,strlen(naiyou),1,file);
				fclose(file);
				printf("成功\n");
			}
			break;
		case 380:/*showfile*/
			printf("%s\n",filename);
			break;
#endif
		case 200:/*delete*/
			line=atol(content);
		case 21:/*add*/
		case 89:/*set*/
			edit=calloc(strlen(naiyou)+strlen(content)+3,1);
			if(line<=0 || (line==1 && strlen(naiyou)==0)) {
				if(strnum(cmd)==21) {
					strcpy(edit,naiyou);
					if(strlen(naiyou)>0)strcat(edit,"\n");
					strcat(edit,content);
					printf("成功\n");
				} else {
					strcpy(edit,naiyou);
					printf("error:そんな行はありません\n");
				}
			} else {
				now=naiyou-1;
				for(nowline=0;nowline<line-1;nowline++) {
					now=strpbrk(now+1,"\n");
					if(now==NULL) {
						strcpy(edit,naiyou);
						printf("error:そんな行はありません\n");
						nowline=-1;
						break;
					}
				}
				if(now==naiyou-1)now=naiyou;
				if(nowline!=-1) {
					memcpy(edit,naiyou,now-naiyou);
					if(strnum(cmd)!=200) {
						if(now!=naiyou)strcat(edit,"\n");
						strcat(edit,content);
						if(now==naiyou)strcat(edit,"\n");
					}
					if(strnum(cmd)!=21)now=strpbrk(now+1,"\n");
					if(now!=NULL)strcat(edit,now);
					printf("成功\n");
				}
			}
			free(naiyou);
			naiyou=calloc(strlen(edit)+1,1);
			strcpy(naiyou,edit);
			free(edit);
			break;
		case 172:/*show*/
			line=atol(content);
			if(line<=0) {
				printf("error:そんな行はありません\n");
			} else {
				now=naiyou-1;
				for(nowline=0;nowline<line-1;nowline++) {
					now=strpbrk(now+1,"\n");
					if(now==NULL) {
						printf("error:そんな行はありません\n");
						nowline=-1;
						break;
					}
				}
				if(nowline!=-1) {
					edit=strpbrk(now+1,"\n");
					if(edit==NULL)edit=naiyou+strlen(naiyou);
					memcpy(cmd,now+1,edit-now-1);
					cmd[edit-now-1]=0;
					printf("%s\n",cmd);
				}
			}
			break;
		case 160:/*exit*/
			free(naiyou);
			exit(0);
		default:
			printf("error:コマンドが不正です\n");
		}
	}
	return 0;
}

long strnum(char* str) {
	long num;
	long i;
	char temp;
	num=0;
	for(i=0;i<strlen(str);i++) {
		temp=str[i]-64;
		if(temp>=33)temp-=32;
		num+=temp*(i+1);
	}
	return num;
}

これはテキストを編集できるラインエディタプログラムだが、そんなことは今はどうでもいい。

3.コンパイルする

lcc txedit.c

としてコンパイルすると通り、実行形式ファイルが生成されるが、

lcc -DCAUSE_OOM txedit.c

としてコンパイルするとout of memoryが出力される。

関連項目