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.
There are a few problems here:
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.
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.
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.
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.
Related
I am programming a simple text editor in C. I have to define inuse_head and free_head as global variables. I need to change the value of the 2 global variables in a function. Here is the code I wrote so far:
#include <stdio.h>
#include <string.h>
struct node
{
char statement[40];
int next;
};
struct node textbuffer[25];
int free_head;
int inuse_head;
void insert(int line, char* stat)
{
FILE *file;
file=fopen("deneme.txt","a");
if(file!=NULL)
{
int i;
int k;
strcpy(textbuffer[line].statement,stat);
textbuffer[line].next=line+1;
fprintf(file,textbuffer[line].statement);
for(i=0;i<=25;i++)
{
if(textbuffer[i].statement==NULL)
{
free_head=i;
break;
}
}
for(k=0;k<=25;k++)
{
if(textbuffer[k].statement!=NULL)
{
inuse_head=k;
break;
}
}
}
else
{
printf("File couldn't found.");
}
fclose(file);
}
int main()
{
insert(3,"Hello World");
printf("free list: %d and inuse list: %d",free_head,inuse_head);
return 0;
}
Now when I print free_head and inuse_head, it prints 0 for both of them. I need to change free_head's and inuse_head's values in function insert. I think I should handle it with pointers but how?
The reason why both variables have the value 0 is not that the function insert is having trouble accessing these variables. Since the variables are both global, the function insert can access both variables directly, like any other variable. It is therefore not necessary to use pointers for accessing these variables.
The problem is rather that in the function insert, the line
free_head=i;
never gets executed, and the line
inuse_head=k;
is only executed once, at a time when k has the value 0.
That is why both variable's values never change their values and both keep their initial value of 0 throughout the entire program.
Also, it is worth noting that your program has undefined behavior. As already pointed out in the comments section, you are accessing the array textbuffer out of bounds.
The line
for(i=0;i<=25;i++)
should be changed to
for(i=0;i<25;i++)
and the line
for(k=0;k<=25;k++)
should be changed to:
for(k=0;k<25;k++)
I was working on an assignment for a simple assembler that should recognize arbitrary variable names like high programming languages. I tried to use Dynamic allocation to an array of char pointers
I am just trying to make an extensible array of strings and being able to search this array for specific strings But it gives a segmentation fault on the line of trying to compare the two strings [line: 14]
Comp(&buffer[1], Variables[i];
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define Comp(a,b) strcmp(a,b) == 0 ? 1 : 0
char buffer[255], **Variables;
int VariableIndex;
void A_instructionHandler() {
int A_Operand, test = 0;
if (buffer[0]== '#') {
for (int i = 0; i <= VariableIndex; i++) {
test = Comp(&buffer[1], Variables[i]);
if (test) {
A_Operand = i + 16;
break;
}
}
}
}
int main(int argumentCounter, char *arguments[]) {
strcpy(buffer, "#variable");
Variables = (char **)calloc(VariableIndex + 1, sizeof(char**));
A_instructionHandler();
}
Here's that code refactored into something more idiomatic:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
void instruction_handler(char* buffer, char** variables) {
switch (buffer[0]) {
case '#':
// This iterates over the NULL terminated array by stopping when
// it hits a NULL pointer, or in other words *v is false.
for (char **v = variables; *v; ++v) {
// If this matches a variable name...
if (!strcmp(*v, &buffer[1])) {
// Variable matched, so show some debugging code
printf("Found variable: %s\n", *v);
return;
}
}
}
}
int main(int argc, char* argv[] ) {
// Create a simple NULL-terminated array of arbitrary size
char *variables[] = {
"variable",
NULL
};
instruction_handler("#variable", variables);
}
Where that variables array can be defined however you like, extended, shrunk, so long as the NULL terminator remains in place at the end.
Some tips based on your original code:
Don't use global variables unless you have an extremely compelling reason. No such reason existed here.
Make your functions clear in intent and purpose.
Pick a naming convention and stick to it.
Use C conventions like strcmp() and just deal with how weird it is, don't wrap that in a #define and invent your own C dialect nobody understands. You'll get used to C over time, it won't bother you as much, and you can code without driving other people on your team up the wall.
Explanations like argc expanded to argumentCounter is better expressed as a comment than an awkwardly long variable name, especially one that's very non-standard. Comments are great. Use them as much as you like!
I have my own data type since C89 doesn't allow bool type. I can't use C99 sadly.
I have tested the below code and my program is not even recognizing that the names are different. The names are working just fine. I have those loaded in an instance of the struct.
struct ROOM roomList [MAX_ROOMS_COUNT];
I used memset and strcpy to copy in a list of rooms from a room array. Testing this gives me the results I want like so...
printf("%s", roomList[1].name)
printf("%s", roomList[2].name)
...
printf("%s", roomList[7].name)
The rooms array has 7 values.
#define MAX_ROOMS_COUNT 7
typedef enum {
true = 1,
false = 0
} boolean;
struct ROOM {
char name[8];
char* type;
int numConnections;
char* connections [MAX_CONNECTIONS_COUNT];
};
boolean isSameRoom(struct ROOM x, struct ROOM y) {
//printf("Is Same Room, 1:%s, 2:%s\n", x.name, y.name);
if (x.name == y.name) {
//printf("ROOM IS SAME!");
return true;
}
else {
return false;
}
}
struct ROOM getRandomRoom() {
int random = rand() % MAX_ROOMS_COUNT;
return roomList[random];
}
void addRandomConnection() {
struct ROOM A;
struct ROOM B;
A = getRandomRoom();
do {
B = getRandomRoom();
}while(isSameRoom(A, B) == true);
//printf("Add Random Connection, 1:%s, 2:%s\n", A.name, B.name); //for testing purposes
}
Using the print statements I can see that the isSameRoom function isn't working. It's generating random rooms just fine, but there are instances when I run the program that I'm getting the same room for A and B. Any idea why? Thanks! :)
First of all, you're using pass-by-value for these structures, which is pretty inefficient. You should do pass by reference.
Second, as others mentioned, you cannot compare fixed-size strings with == in C; you have to use strncmp or some other structure.
Perhaps a better idea would be to do the whole comparison of the whole structure with memcmp?
return memcmp(&A, &B, sizeof(struct ROOM)) == 0;
#include <stdio.h>
#include <string.h>
void increase(char **tab)
{
int i=strlen(*tab);
int o=i;
while((*tab)[i]!='5' && i>=0)
{
i--;
}
if(i>=0)
{
int tt;
char array[o+1];
for(tt=0;tt<o;tt++)
{
if(tt!=i)
array[tt]=(*tab)[tt];
else
array[tt]='6';
}
array[o]='\0';
*tab=array;
// printf("\n%s",*tab);
}
else
{
char array[o+2];
int tt;
for(tt=0;tt<=o;tt++)
{
array[tt]='5';
}
array[o+1]='\0';
*tab=array;
// printf("\n%s",*tab);
}
}
int main()
{
int n;
char *test;
test="555";
increase(&test);
printf("\n%s",test);
return 0;
}
Okay, so increase() is meant to replace number in test with the next number containing only 5 and 6.
What I wanted to do is to change the value of test directly by using pointer to char*. Everything seems to work just fine untill it comes to displaying changed value - it simply won't show unless was asked to do it inside the
increase() function. Once I add
printf("\n%s",*tab);
inside any of conditions (commented), everything works just fine (excluding showing a double result).
What causes a problem here?
555 is just a testing value, actually any number made of 5s or 6s will do the work.
Lines like *tab=array; cause a problem, given that array is a local variable that goes out of scope when its enclosing block ends. In main(), test now points to memory that's invalid, and trying to use it is undefined behavior.
I'm just starting on the road the learning C, and ran into some difficulty:
The code listed below is giving me the following error:
Attaching to program: `/workfolder/cocoa/c_stuff/bookshelf/build/Debug/bookshelf', process 1674.
Cannot access memory at address 0xa0df194
Cannot access memory at address 0xa0df194
// code start
#define MAX_NAME_LENGTH 200
#define MAX_AUTHOR_LENGTH 200
#define MAX_DESCRIPTION_LENGTH 1000
#define MAX_PUBLISHER 200
#define MAX_ISBN 50
//structures<
typedef struct {
char title[MAX_NAME_LENGTH];
char author[MAX_AUTHOR_LENGTH];
char ISBN[MAX_ISBN];
char description[MAX_DESCRIPTION_LENGTH];
char publisher[MAX_PUBLISHER];
} Book;
void getUserInput(Book *s[])
{
printf("what is the book's title ?\n");
fgets(s[book_count]->title, MAX_NAME_LENGTH, stdin);
printf("what is the author's name?\n");
fgets(s[book_count]->author, MAX_AUTHOR_LENGTH, stdin);
printf("what is the ISBN?\n");
fgets(s[book_count]->ISBN, MAX_ISBN, stdin);
printf("write a short description\n");
fgets(s[book_count]->description, MAX_DESCRIPTION_LENGTH, stdin);
printf("what is the book's publisher\n");
fgets(s[book_count]->publisher, MAX_PUBLISHER, stdin);
printf("want to add another book ? Y\\N\n");
book_count++;
if(tolower(fgetc(stdin)) == 'y')
{
return getUserInput(s);
}
else
{
return;
}
}
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
if((book_shelf[0] = (Book *)malloc(sizeof(Book))) == NULL)
{
exit(1);
}
getUserInput(book_shelf);
return 0;
}
The code compiles properly, and the function runs fine the first time (all the questions get asked and the struct receives the data); but when the user types 'y' to add another book, the mem error occurs.
Any ideas where the error is happening?
Thanks in advance!
You've only ever allocated memory for the first book in main - after that it tries to write to the next slot in the array, which doesn't point to an allocated block of memory, giving you a seg-fault. You're going to have to allocate memory for each book you want to read in.
In addition, since C doesn't know how long an array is, you have to pass that information along into function calls. (And I don't see where you're defining book_count.)
You might try something along these lines:
void getUserInput(Book *s[], int *book_count, int max_book_count)
{
if (book_count == max_book_count) return; // If we've filled all the slots, we can't add anymore without causing trouble.
s[book_count] = malloc(sizeof(Book));
..
if(tolower(fgetc(stdin)) == 'y')
{
(*book_count)++;
getUserInput(s, book_count, max_book_count);
}
return;
}
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
int book_count = 0;
getUserInput(book_shelf, &book_count, 100);
// Make sure to free all the malloc'd data
}
Even better in this situation, would just be using a loop and skipping the whole recursion step.
int main (int argc, const char * argv[]) {
// insert code here...
Book *book_shelf[100];
char response = 'y';
int book_count = 0;
while (book_count < 100 && response == 'y')
{
book_shelf = malloc(sizeof(Book));
response = getUserInput(book_shelf[book_count++]);
}
// make sure to free all the allocated data!
}
char getUserInput(Book *book)
{
// write input straight to book
printf("what is the book's title ?\n");
fgets(book->title, MAX_NAME_LENGTH, stdin);
...
return tolower(fgetc(stdin));
}
Unless I'm reading something wrong, you haven't defined book_count before using it as an array subscript.
Within main, you allocated on the stack an array of 100 pointers to the Book Structure. I believe it was your intent to allocate 100 structures and then pass the address to that block of structures to getUserInput
Change main to:
Book book_shelf[100];
...
getUserInput(book_shelf);
...
EDIT: OOPS Missed the single Book malloc mentioned in the earlier post. That ones Correct for the first book. If you edit as above and eliminate the
if (book_shelf[0]...) check, you'll accomplish your intended results
You allocate just space for the firstbook, not for the others (malloc in main)
I guess there is some code missing, no declaration and initialization of book_count
You should use loops instead of recursion
Use not recursion but loops for this kind of repetition
Recursion is probably overkill for this problem where a simple do { ... } while(user keeps answering yes) would do. However the problem you having is in main with your Book *book_shelf[100]. There are several ways you could solve this problem.
First change it to an array of Book's like samills suggests:
Book book_shelf[100];
and then change your getUserInput to something like this:
getUserInput(Book *book_shelf, int offset, int length) {
if(offset < 0 || offset >= length) {
return;
}
//...
return getUserInput(book_shelf, offset + 1, length)
}
Or you could use your existing code and change you getUserInput function to look something like this and remove the malloc from main:
getUserInput(Book *book_shelf) {
book_shelf[book_count] = (Book*)malloc(sizeof(Book));
// ...
}
props for correct use of the sizeof operator (I see that thing misused so often it makes my eyes bleed).
As in Josh's answer, by adding the following lines to your code should make it work:
book_count++;
if(tolower(fgetc(stdin)) == 'y')
{
if((book_shelf[book_count] = (Book *)malloc(sizeof(Book))) == NULL)
{
printf("Cannot allocate memory for Book");
exit(1);
}
return getUserInput(s);
}
else
{
return;
}
However, I encourage you not to use the recursive function for getting input. Recursive can lead to difficulties in debugging. You may consider using normal loop instead.
Note: I'm assuming the book_count is global variable which has been initialized to 0
thanks a lot for the replies!
I realized that I hadn't malloc-ed enough memory to handle more then one element of the struct array (Exactly what Josh is saying). So essentially:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
so the second time around I would hit a memory issue.
thanks again!
Looks like your still doing it wrong:
Book *book_shelf;
if(book_shelf = (Book*)malloc(sizeof(Book)) == NULL)//exit code
book_shelf is only the size of a pointer. When you do the malloc you only allocate one Book at a time. This is wrong. You need to allocate contiguous memory for an array of Book objects all in one instanciation of an array.
Like
Book book_shelf[100];
not
Book *book_shelf[100];
or using malloc, use your pointer to point to an array instanciated using
100*malloc(sizeof(Book)).
You may get lucky that no other heap memory is allocated in between your malloc(sizeof(Book)) calls and that the memory management system is alocating contiguous memory by default. Also, book_shelf will only point to the last malloced Book structure, not the first one as you indicated you want in your original question.
Josh is also not allocating enough memory at one time. Use a linked list if you want to keep extending elements to the end of your book_shelf one-by-one.
factorial with pointer and recursion
#include<iostream.h>
#include<conio.h>
int show(int *p)
{
int f;
int x=*p;
if(*p==1) //boundry checking for recursion
return 1;
else
f=x*show(&(--*p)); //this code is similar to f=x*show(n-1); with non-pointers
return f;
}
void main()
{
int a=6;
int b=show(&a);
cout<<b;
getch();
}