-4

I'm trying to code a Turing machine in C. But my program doesn't work, it gets stuck in an endless loop. Here's my code with some explanations:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define N 3  //number of different states for the cells
#define K 20 //length of the tape


typedef struct
{
int state;
int head;
char tape[];
}mt;  //machine

void init_mt(mt* machine, char val[], int n)
{
machine->state=1; //edited mistake
machine->head=0; // edited mistake
int i;
for(i=0;i<n;i++)
    {
       machine->tape[i]=val[i];
    }
}; //initialization of a machine


typedef struct
{
char write;
char direction;
int state;
}actions; //actions composed of three instructions

typedef struct
{
 actions exec01;
 actions exec02;
 actions exec11;
 actions exec12;
}program; //program composed of four actions

void execute(actions exec, mt mach)
{
    mach.tape[mach.head] = exec.write;
    mach.state = exec.state;

  if(exec.direction == 'R')
    {
         mach.head++;
    }
  else
   {
        mach.head--;
   }
} //class that follows the instructions from the actions

void execute2(mt mach, program p)
{  do{
printf("%c %d %d \n", mach.tape[mach.head], mach.head, mach.state );

if(mach.tape[mach.head] == 0)
{

    if(mach.state == 1)
    {
        execute(p.exec01, mach);
    }
    else if(mach.state == 2)
    {
        execute(p.exec02,mach);
    }
}
else if(mach.tape[mach.head] == 1)
{
    if(mach.state == 1)
    {
        execute(p.exec11,mach);
    }
    else if(mach.state == 2)
    {
        execute(p.exec12,mach);

    }
}

}while( (mach.head<K) && (mach.state != 3));
} // class that read the program and act according to the states of the cells, 
//keeps going until the machine is at the third state or if it reaches the end of the tape


int main(){
mt machine;
char t[10]={'1','1','1','0','0','1','0','1','0','1'};
init_mt(&machine, t, 10);
program p ={ {'0','R',1}, {'0','R',1}, {'1','R',2}, {'0','L',3} };
execute2(machine, p);
return 0;
} //main with a tape composed of 10 cells and a program composed of four actions

This program keeps displaying "0,0,1" indefinitely and I can't find the error. Thanks for the help and sorry if this unclear.

gzzzzz
  • 9
  • 5
  • 2
    This doesn't compile. `mt` has no members `etat` and `tete`. How about posting the code you're actually using? – Tom Karzes Apr 28 '16 at 01:34
  • Presumably you wanted `exec` to modify "the" turing machine, not the **copy** that you passed to it, right? Why doesn't `void f(int x) {x++;} int main() {int i = 5; f(i); printf("%i\n", i); return 0;}` print 6? – user253751 Apr 28 '16 at 02:36
  • `mt machine; .. init_mt(&machine, t, 10);` but `machine.tape` have no memory. – BLUEPIXY Apr 28 '16 at 02:48
  • Thanks for the answers. – gzzzzz Apr 28 '16 at 07:24
  • @TomKarzes Sorry I thought it would be easier to translate the names of the classes to make it more clear, I edited it, it works now. – gzzzzz Apr 28 '16 at 07:35
  • @immibis I get what you're saying, in your exemple the i from main is not actually modified, Do you mean that my class execute is not actually doing anything to the machine? Oh I have to use a pointer, right? – gzzzzz Apr 28 '16 at 07:35
  • @BLUEPIXY I'm not sure I understand, I thought I reserved some memory with `char tape[]` in `typedef struct{}mt` – gzzzzz Apr 28 '16 at 07:36
  • Have you enabled compiler warnings and run the program through valgrind and asan? – Kerrek SB Apr 28 '16 at 08:20
  • @KerrekSB No, I'm not familiar with these things, is that necessary? – gzzzzz Apr 28 '16 at 08:30
  • @gzzzzz: Well, there are a lot of really powerful automatic tools that can solve 90% of your problems without you ever having to ask any broad questions. It's probably worth your (and our) time for you to learn them, especially if you plan building a life around programming. – Kerrek SB Apr 28 '16 at 08:35
  • @KerrekSB Alright I'll look into it, for now I'd like to understand what I did wrong. – gzzzzz Apr 28 '16 at 08:48
  • `char tape[] in typedef struct{}mt` Just will not be that you have to ensure the memory it. see [DEMO](http://ideone.com/KWUL2M) – BLUEPIXY Apr 28 '16 at 11:34
  • @BLUEPIXY Ok I understand, thank you – gzzzzz Apr 28 '16 at 23:35

2 Answers2

0

In function execute, you pass the structure mach by value. In that function you also perform

mach.head++

This, value presumably should be given back to the function execute2. So you will have to pass the structure mach by reference to this function.

Rishikesh Raje
  • 8,556
  • 2
  • 16
  • 31
0

There are a few problems here:

  1. In some instances you're passing your structures as arguments, rather than pointers to them. This creates local copies of the entire structures in the called function. Any changes made to those copies will be lost when the functions return. It is also inefficient. Just pass structure pointers.

  2. You aren't declaring any space for tape in your structures, so it's basically a zero-length array. Any kind of access whatsoever will corrupt memory and result in undefined behavior. You have a couple choices here. You can either choose some fixed size for it, and use that for the array size, or you can change it to a pointer and dynamically allocate storage for it. One way or another, you have to allocate the storage.

  3. In execute2, it's comparing mach.tape[mach.head] to the integers 0 and 1. But the tape doesn't contain those values. It contains the characters '0' and '1'. So surround those constants with single quotes. It would also be a good idea to print an error if an unexpected value is encountered. That would have caught this problem instantly.

Tom Karzes
  • 22,815
  • 2
  • 22
  • 41
  • 1. I changed the structures in pointers to structures, it now shows 1,0,1 2. How would I do that? I tried to put `char tape[10];` in `typedef struct{}mt` but it doesn't change anything. – gzzzzz Apr 28 '16 at 09:19