Updating array in a function causes pointer lose - c

I am trying to divide my code into functions, I have a sample code of "Game Of Life".
However, when I try to initialize 2D grid array in a function, gnuplot gives no valid data points error.
These are global variables declared before main:
static char **currWorld=NULL, **nextWorld=NULL
This is the original logic to init game grid, but this part is in main.
if (game == 0){ // Use Random input
for(i=1;i<nx-1;i++){
for(j=1;j<ny-1;j++) {
currWorld[i][j] = (real_rand() < prob);
population[w_plot] += currWorld[i][j];
}
}
}
else if (game == 1){ // Block, still life
printf("2x2 Block, still life\n");
int nx2 = nx/2;
int ny2 = ny/2;
currWorld[nx2+1][ny2+1] = currWorld[nx2][ny2+1] = currWorld[nx2+1][ny2] = currWorld[nx2][ny2] = 1;
population[w_plot] = 4;
}
else if (game == 2){ // Glider (spaceship)
printf("Glider (spaceship)\n");
// Your code codes here
}
else {
printf("Unknown game %d\n",game);
exit(-1);
}
This is my function:
int init_game(int choice, int probability){
int i,j;
if (choice == 0){ // Use Random input
for(i=1;i<nx-1;i++){
for(j=1;j<ny-1;j++) {
currWorld[i][j] = (real_rand() < probability);
population[w_plot] += currWorld[i][j];
}
}
}
else if (choice == 1){ // Block, still life
printf("2x2 Block, still life\n");
int nx2 = nx/2;
int ny2 = ny/2;
currWorld[nx2+1][ny2+1] = currWorld[nx2][ny2+1] = currWorld[nx2+1][ny2] = currWorld[nx2][ny2] = 1;
population[w_plot] = 4;
}
else if (choice == 2){ // Glider (spaceship)
printf("Glider (spaceship)\n");
// Your code codes here
}
else {
printf("Unknown game %d\n",choice);
exit(-1);
}
}
and my function call in main:
init_game(game, prob);
value of game is 0, prob is 0.2 and I tested memory allocations and other stuff, they work fine.
Only difference is I moved the logic to a function. How can this happen? My arrays are global, I cannot understand how it cannot be initialized.
This is the gnuplot error:
Skipping data file with no valid points
Since gnuplot and other functions are works fine, I did not add them but if you need any info, I can add.
Here is the link of file itself:
file

Related

C: Bus Error between function returns and execution goes back to parent function

To simplify the problem as much as possible, I have two functions, a parent that calls the child. Everything executes okay till it gets to the return of the child function. After that I get a Bus Error.
int main () {
game();
// this doesn't get executed and program fails with bus error
printf("Execute 2");
return 1;
}
int game () {
game_t GameInfo = {.level = 1, .score = 0, .playerCh = 0, .playerX = 1, .playerY = 1};
gameLevel(&GameInfo);
mvprintw(1,1, "Executed");
// code works up to here and get's executed properly
return 1;
};
void gameLevel (game_t *GameInfo) {
// determine the size of the game field
int cellCols = COLS / 3;
int cellRows = (LINES / 3) - 2;
GameInfo -> playerX = 1;
GameInfo -> playerY = 1;
generateMaze(0);
int solved = 0;
int level = GameInfo -> level;
// default player position
getPlayerDefault(GameInfo);
pthread_t enemies_th;
pthread_create(&enemies_th, NULL, enemies, (void *)GameInfo);
// enemies(&level);
while (solved == 0 && GameInfo -> collision != 1) {
printGameInfo(GameInfo);
noecho();
char move = getch();
echo();
if (GameInfo -> collision != 1) {
if (checkMoveValidity(move, GameInfo) == 1) {
solved = movePlayer(move, GameInfo);
if (solved == 1) {
break;
}
}
} else {
break;
}
}
if (solved == 1) {
pthread_cancel(enemies_th);
GameInfo->level++;
gameLevel(GameInfo);
} else {
// game over
pthread_cancel(enemies_th);
return;
}
}
Now, the code is much more complicated than here, but I think that shouldn't have any influence on this (?) as it executes properly, until the return statement. There is also ncurses and multithreading, quite complex custom structures, but it all works, up until that point. Any ideas ?
Tried putting print statements after each segment of code, everything worked up until this.
pthread_cancel() doesn't terminate the requested thread immediately. The only way to know that a cancelled thread has terminated is to call pthread_join(). If the thread is left running, it will interfere with use of the GameInfo variable in the next level of the game if the current level is solved, or may use the GameInfo variable beyond its lifetime if the current level was not solved and the main thread returns back to the main() function.
To make sure the old enemies thread has terminated, add calls to pthread_join() to the gameLevel() function as shown below:
if (solved == 1) {
pthread_cancel(enemies_th);
pthread_join(enemies_th);
GameInfo->level++;
gameLevel(GameInfo);
} else {
// game over
pthread_cancel(enemies_th);
pthread_join(enemies_th);
return;
}
The use of tail recursion in gameLevel() seems unnecessary. I recommend returning the solved value and letting the game() function start the next level:
In game():
while (gameLevel(&GameInfo)) {
GameInfo.level++;
}
In gameLevel():
int gameLevel(game_t *GameInfo) {
/* ... */
pthread_cancel(enemies_th);
pthread_join(enemies_th);
return solved;
}

Appending values to a struct and printing it

I have just started using structs and I am trying to append the variable names and its contents to the struct variables. For example.
INPUT:
PATH, getenv("PATH")
OUTPUT:
Var Name: PATH
Var Contents: /usr/sbin
This is my struct declaration
int var_counter = 0;
typedef struct ENV_VARIABLES
{
char var_name[MAX_VAR_NAME]; // Stored the Variable Name ie PATH
char var_content[MAX_SIZE]; // Stores the Variable Contents ie \home\bin\shell...
}env_variable;
env_variable *env_vars;
Here I am passing the parameters to the environVars() then printing them.
void iniEnvVars()
{
environVars("PATH", getenv("PATH"));
environVars("PROMPT", shellname);
environVars("CWD", getcwd("CWD", MAX_ARGS));
environVars("USER", getenv("USER"));
environVars("SHELL", "/home/.../");
environVars("TERMINAL", ttyname(STDIN_FILENO));
environVars("EXITCODE", EXITCODE);
printVars();
}
Here I am adding the contents to the struct.
int environVars(char *env_name, char *env_content)
{
// First we want to check if there are any stored items in the struct
// If there isnt, we store the first env_name and its contents;
// Else, we check if it is there, else we add it to the struct.
// If it is already there we modify its contents.
if(var_counter == 0)
{
var_counter++;
env_vars = calloc((size_t)var_counter, sizeof(env_variable));
strcpy(env_vars[var_counter].var_name, env_name);
strcpy(env_vars[var_counter].var_content, env_content);
}
else
{
for(int i = 0; i < var_counter; i++)
{
if(strcmp(env_name, env_vars[i].var_name) == 0)
{
printf("Found\n");
printf("Modifying Variable Contents\n");
strcpy(env_vars[i].var_content, env_content);
break;
}
else
{
var_counter++;
env_vars = realloc(env_vars,(var_counter)*sizeof(env_variable));
strcpy(env_vars[i].var_name, env_name);
strcpy(env_vars[i].var_content, env_content);
break;
}
}
}
return 1;
}
Here I am printing them.
void printVars()
{
if(var_counter == 0)
{
printf("There are no Enviromental Variables stored.\n");
}
else
{
for(int i = 0; i < var_counter; i++)
{
printf("Var Name: %s\n\n ", env_vars[i].var_name);
printf("Var Contents: %s\n\n ", env_vars[i].var_content);
}
}
}
I made use of calloc and realloc, but I am not quite sure if I were supposed to use malloc.
The error occuring is that it is not printing anything.
Ive did run a debug and the same thing happened. Nothing was printing.
Bug #1:
if(var_counter == 0)
{
var_counter++;
env_vars = calloc((size_t)var_counter, sizeof(env_variable));
strcpy(env_vars[var_counter].var_name, env_name);
strcpy(env_vars[var_counter].var_content, env_content);
}
What actually happen when var_counter is zero, is this:
var_counter = 1;
env_vars = calloc(1, sizeof(env_variable));
strcpy(env_vars[1].var_name, env_name);
strcpy(env_vars[1].var_content, env_content);
^
oh dear
You are writing outside the allocated memory
It should be:
strcpy(env_vars[0].var_name, env_name);
strcpy(env_vars[0].var_content, env_content);
Bug #2:
for(int i = 0; i < var_counter; i++)
{
if(strcmp(env_name, env_vars[i].var_name) == 0)
{
printf("Found\n");
printf("Modifying Variable Contents\n");
strcpy(env_vars[i].var_content, env_content);
break;
}
else
{
// YOU DON'T WANT THIS !!
var_counter++;
env_vars = realloc(env_vars,(var_counter)*sizeof(env_variable));
strcpy(env_vars[i].var_name, env_name);
strcpy(env_vars[i].var_content, env_content);
break;
}
}
The else makes reallocate and overwrite old entries again and again. You don't want that.
The code in the else should be after the loop. And only be executed in no match was found in the loop.

C - How to get original value of when you pass a dereferenced value to a function to later be compare with another string?

I know homework help are shunned upon, however, I have intense coder's block.
I want help understanding more than anything.
So when I take the address of the variable (&c) I understand that I get an address to its location in memory, but I don't know how to dereference that address in order to access its specific value ('b') to be compared in the function (color(&c, total) it is used in.
The main cannot be changed for any reason due to the requirements of the assignment
typedef struct dragon
{
char *name;
char *color[3];
int numHead;
int numTail;
}dragon;
void color(char* color, dragon *d);
int main()
{
dragon total[4];
dragon_info(total);
char c = 'b';
color(&c, total);
return 0;
}
Eventually, I used this line to see if the colors matched
if(strcmp(color, d[currentDra].color[currentColor]);
Before I used the line below because from my from my first perspective they would char
if(color == d[currentDra].color[currentColor])
But after debugging for a while I realized that color was just an address
Overall, I need to somehow get the value of color using the address somehow.
*color doesn't find the value.
&color doesn't either.
The rest of the function
void color(char *color, dragon *d)
{
char *colorList[5] = {"red","blue","white","green","yellow"};
int colorShow;
int knownColor = 1;
printf("what is color? ==== %p\n", color);
if(*color == 'r')
{
colorShow = 0;
}
else if(*color == 'b')
{
colorShow = 1;
}
else if(*color == 'w')
{
colorShow = 2;
}
else if(*color == 'g')
{
colorShow = 3;
}
else if(*color == 'y')
{
colorShow = 4;
}
else
{
printf("Sorry that is an unknown color, exiting...\n");
knownColor = 0;
}
//if a char then = numbers 0-1
//one loop for the dragons
if(knownColor)
{
printf("***All the %s dragons:***\n", colorList[colorShow]);
int currentDra;
for(currentDra = 0; currentDra < 4; currentDra++)
{
//another loop for the colors of the dragon
int currentColor;
for(currentColor = 0; currentColor < 3; currentColor++)
{
//printf("%c\n\n", (char*)color);
if(strcmp(color, d[currentDra].color[currentColor]))
{
printf("%s is %s\n", d[currentDra].name, colorList[colorShow]);
}
}
}
}
}
Thank you so much this is my first question ever.
if(strcmp(color, d[currentDra].color[currentColor]);
This doesn't work because color, as passed, is not null terminated. Thus this is undefined behavior.
if(color == d[currentDra].color[currentColor])
This doesn't work because you are comparing the pointers and not the values they reference.
If dragon.color is an array that contains single character strings, then you can compare with:
if(color[0] == d[currentDra].color[currentColor][0])

Linked List won't return to main function when head is deleted and moved forward

I'm currently stuck at this part in coding a dictionary projects. I can pretty much breeze through everything else, but here.
My problem is that whenever I return the dictionary(a linked list head) to the main function after it passes through this particular if statement, an exception pops out.
item *deleteEntry(item *entry, item *dictionary)
{
item *cont,*temp;
int check;
check = 0;
for (cont = dictionary; cont != NULL; cont = cont->next)
{
if (!strcmp(cont->word, entry->word) && cont == dictionary)
{
dictionary = cont->next;
free(cont);
check = 1;
break;
}
//other non-problematic entry-deletion statements
}
if (!check)
return 0;
return dictionary;
}
Even though it does store the data correctly inside the function(I've tested by printing), it just doesn't work when returned to the main function.
Here's the part where I call the function
printf("\nEnter word to delete entry: ");
getchar();
fgets(entry->word, WORDLIMIT, stdin);
if (dictionary[toupper(entry->word[0]) - 65] == NULL)
printf("\nWord Does not exist");
else
{
cont = deleteEntry(entry, dictionary[toupper(entry->word[0]) - 65]);
if (cont)
dictionary[toupper(entry->word[0] - 65)] = cont;
else
printf("\nError: Word doesn't exist in archive %d!!\n", toupper(entry->word[0]));
And the exception is :
Access violation reading location 0xDDDDDDDD. (I don't know what this is, even after google searches. please enlighten me)
And this is my first post here, so I'll take my chance to say Thank you for this is the first place I go to whenever I get stuck :)
Problem Solved!
As I commented, I think the key point is dictionary[toupper(entry->word[0] - 65)]
This code causes to access your array of pointers out of bounds.
E.g.
entry->word[0] = 'a'
toupper(entry->word[0] - 65) = 32
But I think that your array has 26 elements.
It must be
dictionary[toupper(entry->word[0]) - 65]
/* this is part of your code. check comments added by me
*/
for (cont = dictionary; cont != NULL; cont = cont->next /*->next can be null*/)
{
if (!strcmp(cont->word, entry->word) && cont == dictionary)
{
dictionary = cont->next; /*if ->next above is null than boom (null->null)*/
free(cont);
check = 1;
break;
}
//other non-problematic entry-deletion statements
}
/* better use this */
cont = dictionary->next;
while(cont){
if(...){
dictionary=cont->next;
free(cont);
break; /* or return something*/
}
cont=cont->Next;
}
/*return other thing*/

Process exited with return value 255, w/pointers to structures

I have some functions that should allow me to manage a structure which was allocated dynamically. The allocation of the memory and the input of data in those is no real problem, though my program stops when it reaches a certain line of code: (No warning or problems detected)
if(codeV == p_vendite[ctrl_j].p_venditore[ctrl_i].codVenditore)
This line is in the function called VenditeProdotto(Vendite *p_vendite).
Here's the important part of the code (defining structures)
typedef struct _Venditore {
int codVenditore;
int codProdotto;
int qty;
} Venditore;
typedef struct _Vendite{
int mmGG;
Venditore *p_venditore;
} Vendite;
void AggiungiVendita (Vendite *p_vendite);
void VenditeProdotto(Vendite *p_vendite);
void VenditeVenditore(Vendite *p_vendite);
...
Here's main():
int main() {
int check, i, count, flag, choice;
Vendite *p_Vendite;
...
...
p_Vendite = (Vendite*) calloc(numVenditori,sizeof(Vendite));
...
...
p_Vendite->p_venditore = (Venditore*)calloc(numVenditori,sizeof(Venditore));
/*menu*/
flag = TRUE;
do{
choice = menu();
switch (choice) {
case 1 : AggiungiVendita(p_Vendite); break;
...
case 3 : VenditeProdotto(p_Vendite); break;
case 4 : VenditeVenditore(p_Vendite); break;
...
}
} while (flag == TRUE);
return 0;
}
And here are the functions:
void AggiungiVendita (Vendite *p_vendite) {
int flag, check, answer;
i = 0;
do{
/*input of struct - codVenditore,codProdotto,qty*/
...
check = scanf("%d", &(p_vendite[j].p_venditore[i].codVenditore));
...
/*input*/
check = scanf("%d", &(p_vendite[j].p_venditore[i].codProdotto) );
...
/*controllo sull'input*/
check = scanf("%d", &(p_vendite[j].p_venditore[i].qty) );
...
...
//asking to redo or quit
} while(flag == TRUE && i < numVenditori);
return;
}
int menu() {
//just a standard menu, no problem here
...
return choice;
}
void VenditeProdotto(Vendite *p_vendite) {
int check = 0, codeP = 0, ctrl_i = 0, ctrl_j = 0; //ctrl_i,ctrl_j are increasing variables and I use them to search among the structures
...//input, continues after
Where I find the debug error: (line 3 after this)
for(ctrl_j = 0; ctrl_j < numVendite; ctrl_j++) {
for(ctrl_i = 0; ctrl_i < numVenditori; ctrl_i++) {
if (codeP == p_vendite[ctrl_j].p_venditore[ctrl_i].codProdotto)
printf("\nSeller %d, quantity sold: %d in day %d", p_vendite[ctrl_j].p_venditore[ctrl_i].codVenditore, p_vendite[ctrl_j].p_venditore[ctrl_i].qty, ctrl_j+1);
else
continue;
}
}
return;
}
Basically I don't know if it's really legit to use the first line of code that I've talked about, with . instead of ->, but if I try to change the syntax I get detected errors. Any ideas?
At first I thought about something like (p_vendite+ctrl_j)->(p_venditore+ctrl_i)->codProdotto, since it's a pointer but it doesn't seem working.
There are a couple of obvious bugs:
Allocation of Vendite
You're allocating numVenditori elements for p_Vendite, but later on you are iterating numVendite times over the same pointer:
p_Vendite = (Vendite*) calloc(numVenditori,sizeof(Vendite));
...
for(ctrl_j = 0; ctrl_j < numVendite; ctrl_j++) {
for(ctrl_i = 0; ctrl_i < numVenditori; ctrl_i++) {
if (codeP == p_vendite[ctrl_j].p_venditore[ctrl_i].codProdotto)
The allocation should read:
p_Vendite = (Vendite*) calloc(numVendite,sizeof(Vendite));
or as I would prefer it:
p_Vendite = calloc (numVendite, sizeof *p_Vendite);
Allocation of Venditore
p_Vendite->p_venditore = (Venditore*)calloc(numVenditori,sizeof(Venditore));
You're only allocating the p_venditore element for one of your Vendite structs. You need to allocate all of them in a loop:
for (int j = 0; j < numVendite; j++) {
p_Vendite[j].p_venditore = (Venditore*)calloc(numVenditori,sizeof(Venditore));
// And check for allocation errors
}

Resources