out of memory
ナビゲーションに移動
検索に移動
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が出力される。