im having problems with realloc "realloc():invalid old size" - c

hi i've been doing some coding with dynamic memory and double pointers, and work fine in the first part, but when it starts executing the second part(the second double pointer) which is exactly coded as the first one it stops working
main.c.
int main(int cant,char **argv)
{
int troden;
if(cant != 3)
{
printf("papu ta mal /n");
}
else
{
troden = archivOrden(*(argv + 1),*(argv + 2));
}
return 0;
}
function.c
#include "funciones.h"
int archivOrden(char *fileName1,char *fileName2)
{
FILE *arch1 =NULL,*arch2 = NULL;
char **vec1 = NULL;
char **vec2 = NULL;
char **aux = NULL;
int ret = 0;
int i = 0, j = 0, x = 0;
int a;
arch1=fopen(fileName1,"r");
arch2=fopen(fileName2,"r");
if(arch1 == NULL || arch2 == NULL)
{
printf("error al querer crear arch \n");
}
else
{
vec1 = (char**)malloc(sizeof(char)*1);
vec2 = (char**)malloc(sizeof(char)*1);
if(vec1 == NULL || vec2 == NULL) ret = -1;
if(ret == 0)
{
*vec1 = (char*)malloc(sizeof(char)*1);
*vec2 = (char*)malloc(sizeof(char)*1);
if(*vec1 == NULL || *vec2 == NULL) ret = -1;
if(ret == 0)
{
while(!feof(arch1))
{
*(vec1+j) = realloc(*(vec1+j),sizeof(char)*(1+i));
fread((*(vec1+j)+i),sizeof(char),1,arch1);
if(*(*(vec1+j)+i) =='\n')
{
*(*(vec1+j)+i) = '\0';
printf("%s \n",*(vec1+j));
j++;
i = 0;
vec1 = realloc(vec1,sizeof(char)*(1+j));
*(vec1+j) = (char*)malloc(sizeof(char)*(1+i));
}
else i++;
}
*(vec1+j) = realloc(*(vec1+j),sizeof(char)*(1+i));
*(*(vec1+j)+i) = '\0';
i = 0;
while(!feof(arch2))
{
*(vec2+x) = realloc(*(vec2+x),sizeof(char)*(1+i));
fread((*(vec2+x)+i),sizeof(char),1,arch2);
if(*(*(vec2+x)+i) =='\n')
{
//pongo un \0 en el final de la linea
*(*(vec2+x)+i) = '\0';
printf("%s \n",*(vec2+x));
// paso a la siguiente linea
x++;
i = 0;
vec2 = (char**)realloc(vec2,sizeof(char)*(1+x));
*(vec2+x) = (char*)malloc(sizeof(char)*(1+i));
}
else i++;
}
*(vec2+x) = realloc(*(vec2+x),sizeof(char)*(1+i));
*(*(vec2+x)+i) = '\0';
printf("paso por aca \n");
for(a = 0;a<j;a++)
{
printf("%d: %s /n",a,*(vec1+j));
}
for(a = 0;a<x;a++)
{
printf("%d: %s \n",a,*(vec2+a));
}
}
}
}
printf("finalice \n");
fclose(arch1);
fclose(arch2);
for(a = 0;a<j;a++)
{
free(*(vec1+a));
}
for(a = 0;a<x;a++)
{
free(*(vec2+a));
}
free(vec1);
free(vec2);
return ret;
}
it breaks when it starts the second while and reaches the first '/n',
but i cant understand because i do the exact same in the first while and works perfectly fine.

Related

how do i fix this code that _ insert zone, delete_zone, print_zone

For the creation of the map, the user is left with the possibility of requesting the following four functions via a menu with one (switch):
Insertion of a zone at the end of the insert_zone function list. It creates the new zone in dynamic memory malloc, inserts it in the list by modifying the value of the next_zone pointer of the last land in the list with the result of the malloc. The type of the zone as well as the object found within the zone are randomly generated: all zones are equiprobable, no_object has a 40% probability while the other objects in the enum Object_type_zone have equal probability. Finally, the enum field Tipo_prova prova will be inserted with a certain probability every time a player arrives in a given zone see function advance .
Delete the last zone inserted in the path cancel_zone
Print the fields of all the zones created up to that moment print_map.
i leaves the possibility to the user to use a menu to perform the following four functions:
insert_zone: delete_zone: print_map;
.
I leave a copy of the file.h (works well); "you can help to find the solution for the problem"
#ifndef H_GAMELIB
#define H_GAMELIB
extern void imposta_gioco();
extern void gioca();
extern void termina_gioco();
extern void inserisci_zona();
extern void stampa_mappa();
extern void chiudi_mappa();
extern void cancella_zona();
enum Tipo_Difficolta { dilettante, intermedio, incubo };
enum Tipo_oggetto_iniziale { EMF, spirit_box, videocamera, calmanti, sale };
enum Tipo_oggetto_zona { adrenalina, cento_dollari, coltello, calmanti1, nessun_oggetto };
enum Tipo_zona { caravan, cucina, soggiorno, camera, bagno, garage, seminterrato };
enum Tipo_prova { prova_EMF, prova_spirit_box, prova_videocamera, nessuna_prova };
struct Zona_mappa {
enum Tipo_zona zona;
enum Tipo_prova prova;
enum Tipo_oggetto_zona oggetto_zona;
struct Zona_mappa* prossima_zona;
};
struct Giocatore {
char nome_giocatore[30];
unsigned char sanita_mentale;
struct Zona_mappa* posizione;
unsigned char zaino[4];
};
#endif
main.c
#include "gamelib.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <stddef.h>
#include <time.h>
int main (void){
unsigned short numero;
int c = 0;
printf("\033[1;35m ____ ____ ____ ____ ____ ____ ____ ____ \n");
printf(" ||P |||h |||a |||l |||s |||o |||P |||h ||\n");
printf(" ||__|||__|||__|||__|||__|||__|||__|||__||\n");
printf(" |/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|/__\\|\n");
printf("\033[0m\n");
printf("||preme 'invio' per continuare||\n");
while(getchar()!= '\n');
do{
printf("\n");
printf("> \033[1;93m1\033[1m: Imposta Gioco.\n");
printf("> \033[1;96m2\033[2m: Gioca.\n");
printf("> \033[1;91m3\033[3m: Termina gioco.\n\n");
printf ("\033[92mScelta:\033[0m ");
scanf("%hu",&numero);
while ((c = getchar()) != '\n' && c != EOF); //pulizia dei buffer
switch(numero){
case 1:
printf("hai inserito il primo numero\n");
imposta_gioco();
break;
case 2:
printf("hai inserito il secondo numero\n");
gioca();break;
case 3:
printf("hai inserito il terzo numero");
termina_gioco();break;
default: printf("\033[31mAttenzione!\033[0m Opzione non valida, per favore inserisci \033[31mun numero da 1 a 3\033[0m.\n");
}
}while (numero != 3);
return 0;
}
gamelib.c
#include <stdio.h>
#include <stdlib.h>
#include <memory.h>
#include <time.h>
#include "gamelib.h"
#define ERROR_ARGS_NUM(_min, _max) printf("\033[31mAttenzione!\033[5m Opzione non valida, per favore inserisci \033[31mun numero da " #_min " a " #_max "\033[0m.\n")
#define CHECK_NUM_INPUT_RANGE(n, _min, _max)
struct Zona_mappa *pLast = NULL;
struct Zona_mappa *pFirst = NULL;
static struct Giocatore players[4];
static int nplayers = 0;
static int difficulty_level;
int ask_num(const char *prompt)
{
if (prompt)
printf("%s", prompt);
int n;
if (scanf("%d", &n) <= 0)
n = -1;
return n;
}
void mostra_zaino(struct Giocatore *giocatore)
{
const char *nome_oggetto_iniziale;
switch (giocatore->zaino[0])
{
case EMF:
nome_oggetto_iniziale = "EMF";
break;
case spirit_box:
nome_oggetto_iniziale = "Spirit Box";
break;
case videocamera:
nome_oggetto_iniziale = "Videocamera";
break;
case calmanti:
nome_oggetto_iniziale = "Calmanti";
break;
case sale:
nome_oggetto_iniziale = "Sale";
break;
default:
return;
}
printf("Contenuto zaino di %s:\nOggetto iniziale: %s\n", giocatore->nome_giocatore, nome_oggetto_iniziale);
for (int i = 1; i < 3; i++)
{
switch (giocatore->zaino[i])
{
case cento_dollari:
printf("100$\n");
break;
case nessun_oggetto:
printf("nessun_oggetto\n");
break;
case coltello:
printf("coltello\n");
break;
case calmanti1:
printf("calmanti1\n");
break;
case adrenalina:
printf("adrenalina\n");
break;
}
}
printf("\n");
}
void imposta_gioco()
{
srand(time(NULL));
memset(players, 0, sizeof(players));
nplayers = ask_num("Inserisci il numero di giocatori (da 1 a 4): ");
CHECK_NUM_INPUT_RANGE(nplayers, 1, 4);
printf("Scegli il livello di difficoltà:\n");
printf("> \033[1;93m1\033[0m: Dilettante\n");
printf("> \033[2;93m2\033[0m: Intermedio\n");
printf("> \033[3;93m3\033[0m: Incubo\n");
difficulty_level = ask_num("\033[32mInserisci il numero corrispondente: ");
CHECK_NUM_INPUT_RANGE(difficulty_level, 1, 3);
for (int i = 0; i < nplayers; i++)
{
printf("Inserisci il nome del giocatore %d: ", (i + 1));
if (scanf("%s", players[i].nome_giocatore) <= 0)
return;
players[i].sanita_mentale = 100;
players[i].zaino[0] = rand() % 5;
for (int j = 1; j < 4; j++)
players[i].zaino[j] = nessun_oggetto;
mostra_zaino(&players[i]);
}
}
struct Zona_mappa *genera_mappa()
{
// Crea la prima zona mappa
struct Zona_mappa *prima_zona = malloc(sizeof(struct Zona_mappa));
prima_zona->zona = cucina;
// Crea la seconda zona mappa
struct Zona_mappa *seconda_zona = malloc(sizeof(struct Zona_mappa));
seconda_zona->zona = soggiorno;
prima_zona->prossima_zona = seconda_zona;
// Crea la terza zona
struct Zona_mappa *terza_zona = malloc(sizeof(struct Zona_mappa));
terza_zona->zona = garage;
seconda_zona->prossima_zona = terza_zona;
struct Zona_mappa *quarta_zona = malloc(sizeof(struct Zona_mappa));
quarta_zona->zona = camera;
terza_zona->prossima_zona = quarta_zona;
// Crea la terza zona
struct Zona_mappa *quinta_zona = malloc(sizeof(struct Zona_mappa));
quinta_zona->zona = bagno;
quarta_zona->prossima_zona = quinta_zona;
struct Zona_mappa *ultima_zona = malloc(sizeof(struct Zona_mappa));
ultima_zona->zona = seminterrato;
quinta_zona->prossima_zona = ultima_zona;
ultima_zona->prossima_zona = prima_zona;
// Assegna i valori ai puntatori globali
pFirst = prima_zona;
pLast = ultima_zona;
printf("la lista è pronta\n");
return prima_zona; // Restituisce l'indirizzo della prima zona
}
void inserisci_zona()
{
struct Zona_mappa *nuova_zona = malloc(sizeof(struct Zona_mappa));
if (nuova_zona == NULL)
{
fprintf(stderr, "ERRORE di allocazione di memoria per la nuova zona\n");
return;
}
nuova_zona->zona = rand() % 4;
int r = rand() % 100;
if (r < 80)
{
nuova_zona->zona = cucina;
}
else if (r < 60)
{
nuova_zona->zona = bagno;
}
else if (r < 50)
{
nuova_zona->zona = garage;
}
else if (r < 40)
{
nuova_zona->zona = seminterrato;
}
else if (r < 30)
{
nuova_zona->zona = camera;
}
else
{
nuova_zona->zona = soggiorno;
}
r = rand() % 100;
if (r < 40)
{
nuova_zona->oggetto_zona = nessun_oggetto;
}
else if (r < 60)
{
nuova_zona->oggetto_zona = calmanti1;
}
else if (r < 70)
{
nuova_zona->oggetto_zona = coltello;
}
else if (r < 90)
{
nuova_zona->oggetto_zona = cento_dollari;
}
else
{
nuova_zona->oggetto_zona = adrenalina;
}
// Insert the new zone at the end of the list
if (pFirst == NULL)
{// If the list is empty, set First and Last as the new zone
pFirst = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
else
{
pLast->prossima_zona = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
}
void cancella_zona()
{
// Special case: the list is empty
if (pFirst == NULL)
{
return;
}
// Special case: the list contains a single zone
if (pFirst == pLast)
{
free(pFirst);
pFirst = NULL;
pLast = NULL;
return;
}
// Otherwise, find the last zone in the list and delete it
struct Zona_mappa *p = pFirst;
while (p->prossima_zona != pLast)
{
p = p->prossima_zona;
}
free(pLast);
pLast = p;
pLast->prossima_zona = pFirst;
}
void stampa_mappa()
{
// Caso particolare: la lista è vuota
if (pFirst == NULL)
{
printf("La mappa è vuota\n");
return;
}
printf("Stampa della mappa:\n");
struct Zona_mappa *p = pFirst;
do
{
printf(" - Zona di tipo %d, con oggetto %d\n", p->zona, p->oggetto_zona);
p = p->prossima_zona;
} while (p != pFirst);
}
void chiudi_mappa()
{
gioco_impostato = 1;
}
// Funzione che avvia il gioco
void gioca()
{
{
}
}
// Funzione che termina il gioco
void termina_gioco()
{
}
I have problems in the following 3 blocks of code
void inserisci_zona()
{
struct Zona_mappa *nuova_zona = malloc(sizeof(struct Zona_mappa));
if (nuova_zona == NULL)
{
fprintf(stderr, "ERRORE di allocazione di memoria per la nuova zona\n");
return;
}
nuova_zona->zona = rand() % 4;
int r = rand() % 100;
if (r < 80)
{
nuova_zona->zona = cucina;
}
else if (r < 60)
{
nuova_zona->zona = bagno;
}
else if (r < 50)
{
nuova_zona->zona = garage;
}
else if (r < 40)
{
nuova_zona->zona = seminterrato;
}
else if (r < 30)
{
nuova_zona->zona = camera;
}
else
{
nuova_zona->zona = soggiorno;
}
r = rand() % 100;
if (r < 40)
{
nuova_zona->oggetto_zona = nessun_oggetto;
}
else if (r < 60)
{
nuova_zona->oggetto_zona = calmanti1;
}
else if (r < 70)
{
nuova_zona->oggetto_zona = coltello;
}
else if (r < 90)
{
nuova_zona->oggetto_zona = cento_dollari;
}
else
{
nuova_zona->oggetto_zona = adrenalina;
}
// Insert the new zone at the end of the list
if (pFirst == NULL)
{// If the list is empty, set First and Last as the new zone
pFirst = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
else
{
pLast->prossima_zona = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = pFirst;
}
}
void cancella_zona()
{
// Special case: the list is empty
if (pFirst == NULL)
{
return;
}
// Special case: the list contains a single zone
if (pFirst == pLast)
{
free(pFirst);
pFirst = NULL;
pLast = NULL;
return;
}
// Otherwise, find the last zone in the list and delete it
struct Zona_mappa *p = pFirst;
while (p->prossima_zona != pLast)
{
p = p->prossima_zona;
}
free(pLast);
pLast = p;
pLast->prossima_zona = pFirst;
}
void stampa_mappa()
{
// Caso particolare: la lista è vuota
if (pFirst == NULL)
{
printf("La mappa è vuota\n");
return;
}
printf("Stampa della mappa:\n");
struct Zona_mappa *p = pFirst;
do
{
printf(" - Zona di tipo %d, con oggetto %d\n", p->zona, p->oggetto_zona);
p = p->prossima_zona;
} while (p != pFirst);
}
Here's the fixed code. Required modifications to fix the code are marked and explained with comments at the end of the lines starting with "// Edit:". It is a single file where I inserted the header file. At the end is a small main() to test the code.
#include <stdlib.h>
#include <stdio.h>
#ifndef H_GAMELIB
#define H_GAMELIB
void imposta_gioco (void);
void gioca (void);
void termina_gioco (void);
void inserisci_zona(void);
void stampa_mappa (void);
void chiudi_mappa (void);
void cancella_zona (void);
enum Tipo_Difficolta { dilettante, intermedio, incubo };
enum Tipo_oggetto_iniziale { EMF, spirit_box, videocamera, calmanti, sale };
enum Tipo_oggetto_zona { adrenalina, cento_dollari, coltello, calmanti1, nessun_oggetto };
enum Tipo_zona { caravan, cucina, soggiorno, camera, bagno, garage, seminterrato };
enum Tipo_prova { prova_EMF, prova_spirit_box, prova_videocamera, nessuna_prova };
struct Zona_mappa {
enum Tipo_zona zona;
enum Tipo_prova prova;
enum Tipo_oggetto_zona oggetto_zona;
struct Zona_mappa* prossima_zona;
};
struct Giocatore {
char nome_giocatore[30];
unsigned char sanita_mentale;
struct Zona_mappa* posizione;
unsigned char zaino[4];
};
#endif
static struct Zona_mappa* pFirst = NULL; // Edit: Added since pFirst was missing
static struct Zona_mappa* pLast = NULL; // Edit: Added since pLast was missing
void inserisci_zona(void) {
struct Zona_mappa* nuova_zona = malloc(sizeof(struct Zona_mappa));
if (nuova_zona == NULL)
{
fprintf(stderr, "ERROR of memory allocation for the new zone\n");
return;
}
nuova_zona->zona = rand() % 7; // Edit: enum has 7 enumerators
// Edit: Since zones are equiprobable, above line is sufficient
/*
int r = rand() % 100;
if (r < 80)
{
nuova_zona->zona = cucina;
}
else if (r < 60)
{
nuova_zona->zona = bagno;
}
else if (r < 50)
{
nuova_zona->zona = garage;
}
else if (r < 40)
{
nuova_zona->zona = seminterrato;
}
else if (r < 30)
{
nuova_zona->zona = camera;
}
else
{
nuova_zona->zona = soggiorno;
}
*/
int r = rand() % 100;
if (r < 40)
{
nuova_zona->oggetto_zona = nessun_oggetto;
}
else if (r < 55) // Edit: No object has 40% and all others 15%
{
nuova_zona->oggetto_zona = calmanti1;
}
else if (r < 70)
{
nuova_zona->oggetto_zona = coltello;
}
else if (r < 85) // Edit: No object has 40% and all others 15%
{
nuova_zona->oggetto_zona = cento_dollari;
}
else
{
nuova_zona->oggetto_zona = adrenalina;
}
// Insert the new zone at the end of the list
if (pFirst == NULL)
{
// If the list is empty, set First and Last as the new zone
pFirst = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = NULL; // Edit: Next of last one has to be NULL
}
else
{
pLast->prossima_zona = nuova_zona;
pLast = nuova_zona;
pLast->prossima_zona = NULL; // Edit: Next of last one has to be NULL
}
}
void cancella_zona(void) {
// Special case: the list is empty
if (pFirst == NULL)
{
return;
}
// Special case: the list contains a single zone
if (pFirst == pLast)
{
free(pFirst);
pFirst = NULL;
pLast = NULL;
return;
}
// Otherwise, find the second to last zone in the list
struct Zona_mappa *p = pFirst;
while (p->prossima_zona != pLast)
{
p = p->prossima_zona;
}
free(pLast);
pLast = p;
pLast->prossima_zona = NULL; // Edit: Next of last zone has to be NULL
}
void stampa_mappa(void) {
// Special case: the list is empty
if (pFirst == NULL)
{
printf("The map is empty\n");
return;
}
printf("Map printing:\n");
struct Zona_mappa *p = pFirst;
do
{
printf(" - Zone of type %d, with object %d\n", p->zona, p->oggetto_zona);
p = p->prossima_zona;
} while (p != NULL); // Edit: Iterate until there's no next Zona_mappa which is the case if next is NULL
}
int main(void) {
stampa_mappa();
inserisci_zona();
inserisci_zona();
inserisci_zona();
stampa_mappa();
cancella_zona();
stampa_mappa();
cancella_zona();
cancella_zona();
stampa_mappa();
for (;;);
return 0;
}

How to store strings in a 2D array in C?

I want to store strings in a char * array but I don't know how I can do that.
Each cell in the 2d array can contain letters or numbers with 2 digits.
|_|S|_|
|_|10|_|
|_|W|_|
|_|_|_|
|_|_|_|
I tried this, I used struct:
struct Etage {
char Idsalles[20];
int** etage;
int width;
int height;
};
#include <time.h>
#include <stdio.h>
#include <stdlib.h>
#include "etage.h"
#define COLS 15
#define ROWS 9
Etage *createMap()
{
Etage *e = malloc(sizeof(Etage));
e->width = COLS; // columns
e->height = ROWS; // rows
e->etage = malloc(sizeof(char *) * e->height);
for (int i = 0; i < e->height; i += 1)
{
e->etage[i] = malloc(sizeof(char) * e->width);
for (int j = 0; j < e->width; j += 1)
{
e->etage[i][j] = "0";
}
}
return e;
}
void randomId(Etage *e, int maxSalles)
{
srand(time(NULL));
int i = 0;
if (maxSalles < 10)
{
printf("Seulement %d disponibles, veuiller générer plus de salles.\n", maxSalles);
return;
}
while (i < 10)
{
int id = (rand() % maxSalles) + 1;
int existe = testId(e, id);
if (existe != 1)
{
e->Idsalles[i] = id;
i += 1;
}
}
return;
}
int testId(Etage *e, int id)
{
for (int i = 0; i < 10; i += 1)
{
if (id == e->Idsalles[i])
{
return 1;
}
}
return 0;
}
void printEtage(Etage *e)
{
for (int i = 0; i < e->height; i += 1)
{
for (int j = 0; j < e->width; j += 1)
{
if(e->etage[i][j] == 0){
printf(" ");
}else{
printf("%s", e->etage[i][j]);
printf(" ");
}
}
printf("\n");
}
printf("Id des salles de cette étage: ");
for(int i =0; i <10;i+=1){
printf("%d ",e->Idsalles[i]);
}
printf("\n");
}
void freeEtage(Etage *e)
{
//free(e->etage);
free(e);
}
void placerSalles(Etage* e){
int a=ROWS/2;
int b=COLS/2;
//0 = Haut; 1 = Droite; 2 = Bas; 3 = Gauche
e->etage[a][b] = e->Idsalles[0]+"\0"; // On place la premiere salle au centre de l'étage sa sera le spawner 'S'
srand(time(NULL));
int i = 1;
while(i<10){
int dir = randomDirections();
if(dir==0){ // On se déplace en haut
a = a-1; //On se déplace
if(e->etage[a][b] == 0 && a > 0){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
a = a+1; // Sionon on revien a la derniere case connu
}
}else if(dir==1){ // On se déplace à droite
b=b+1;
if(e->etage[a][b] == 0 && b< e->width){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
b = b-1;
}
}else if(dir==2){ // On se déplace en bas
a = a+1;
if(e->etage[a][b] == 0 && a>e->height){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
a = a-1;
}
}else if(dir==3){ // On se déplace à gauche
b = b-1;
if(e->etage[a][b] == 0 && b>0){
e->etage[a][b] = e->Idsalles[i]+"\0";
i+=1;
}else{
b = b+1;
}
}
}
}
int randomDirections(){
int i = 0;
int id = rand() % 4; // Remplacé 10 par le nbrSalles
//printf("Position: %d\n",id);
return id;
}
I have a good understanding with 2d array but three...
I tried using malloc.
I don't even think this is possible...
If your string is a maximum of 2 characters long (your strings will be 3 chars long)
char array[rows][cols][3] = {{"2", "a", "34"}, ... };
or to use malloc
char (*array)[cols][3] = malloc(rows * sizeof(*array));

Printing string pointers in c

So, essentially I have two files:
File 1:
//
// main.c
// frederickterry
//
// Created by Rick Terry on 1/15/15.
// Copyright (c) 2015 Rick Terry. All rights reserved.
//
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int size (char *g) {
int ofs = 0;
while (*(g+ofs) != '\0') {
++ofs;
}
return ofs;
}
int parse(char *g) {
// Setup
char binaryConnective;
int negated = 0;
// Looking for propositions
int fmlaLength = size(g);
if(fmlaLength == 0) {
return 1;
}
if(fmlaLength == 1) {
if(g[0] == 'p') {
return 1;
} else if (g[0] == 'q') {
return 1;
} else if (g[0] == 'r') {
return 1;
} else {
return 0;
}
}
// Now looking for negated preposition
if(fmlaLength == 2) {
char temp[100];
strcpy(temp, g);
if(g[0] == '-') {
negated = 1;
int negatedprop = parse(g+1);
if(negatedprop == 1) {
return 2;
}
}
}
// Checking if Binary Formula
char arrayleft[50];
char arrayright[50];
char *left = "";
char *right = "";
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
if(fmlaLength != 1 && fmlaLength != 2) {
if(g[0] == '-') {
int negatedBinary = parse(g+1);
if(negatedBinary == 1 || negatedBinary == 2 || negatedBinary == 3) {
return 2;
} else {
return 0;
}
}
int i = 0;
int l = 0;
int p = strlen(g);
for(l = 0; l < strlen(g)/2; l++) {
if(g[l] == '(' && g[p-l-1] == ')') {
i++;
}
}
for(int q = i; q < strlen(g); q++) {
if(g[q] == '(') {
numLeft++;
} else if(g[q] == ')') {
numRight++;
}
arrayleft[q] = g[q];
//printf("%c", arrayleft[i]);
//printf("%s", left);
if((numRight == numLeft) && (g[q+1] == 'v' || g[q+1] == '>' || g[q+1] == '^')) {
arrayleft[q+1] = '\0';
bclocation = q+1;
binaryConnective = g[q+1];
binarypresent = 1;
// printf("The binary connecive is: %c\n", binaryConnective);
break;
}
}
if(binarypresent == 0) {
return 0;
}
int j = 0;
for(int i = bclocation+1; i < strlen(g)-1; i++) {
arrayright[j] = g[i];
j++;
}
arrayright[j] = '\0';
left = &arrayleft[1];
right = &arrayright[0];
//printf("Printed a second time, fmla 1 is: %s", left);
int parseleft = parse(left);
// printf("Parse left result: %d\n", parseleft);
if(parseleft == 0) {
return 0;
}
int parseright = parse(right);
if(parseright == 0) {
return 0;
}
// printf("Parse right result: %d\n", parseleft);
if(negated == 1) {
return 2;
} else {
return 3;
}
}
return 0;
}
int type(char *g) {
if(parse(g) == 1 ||parse(g) == 2 || parse(g) == 3) {
if(parse(g) == 1) {
return 1;
}
/* Literals, Positive and Negative */
if(parse(g) == 2 && size(g) == 2) {
return 1;
}
/* Double Negations */
if(g[0] == '-' && g[1] == '-') {
return 4;
}
/* Alpha & Beta Formulas */
char binaryConnective;
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int binarypresent = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
bclocation = i+1;
binaryConnective = g[i+1];
binarypresent = 1;
break;
}
}
}
/* Connective established */
if(binaryConnective == '^') {
if(g[0] == '-') {
return 3;
} else {
return 2;
}
} else if(binaryConnective == '>') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
} else if (binaryConnective == 'v') {
if(g[0] == '-') {
return 2;
} else {
return 3;
}
}
}
return 0;
}
char bin(char *g) {
char binaryConnective;
char arrayLeft[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
int j = 0;
arrayLeft[j++] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[i+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
return binaryConnective;
}
}
}
return binaryConnective;
}
char *partone(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
for(int k = bclocation+1; k < strlen(g)-1; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
int k = 0;
k++;
return leftSide;
}
char *parttwo(char *g) {
char binaryConnective;
char arrayLeft[50];
char arrayRight[50];
int numLeft = 0;
int numRight = 0;
int bclocation = 0;
int i = 0;
if(g[0] == '(') {
i++;
}
if(g[0] == '-') {
i++;
if(g[1] == '(') {
i++;
}
}
int j = 0;
for(i; i < strlen(g); ++i) {
if(g[i] == '(') {
numLeft++;
} else if(g[i] == ')') {
numRight++;
}
arrayLeft[j] = g[i];
if(numRight == numLeft) {
if(g[i+1] == 'v' || g[i+1] == '>' || g[i+1] == '^') {
arrayLeft[j+1] = '\0';
bclocation = i+1;
binaryConnective = g[i+1];
break;
}
}
j++;
}
int m = 0;
int n = size(g) - 1;
if(g[strlen(g)-1] != ')') {
n++;
}
for(int k = bclocation+1; k < n; k++) {
arrayRight[m] = g[k];
m++;
}
arrayRight[m] = '\0';
char* leftSide = &arrayLeft[0];
char* rightSide = &arrayRight[0];
// printf("%s\n", leftSide);
// printf("%s\n", rightSide);
return rightSide;
}
char *firstexp(char *g) {
char* left = partone(g);
char leftArray[50];
int i = 0;
for(i; i < strlen(left); i++) {
leftArray[i] = left[i];
}
leftArray[i] = '\0';
char binConnective = bin(g);
int typeG = type(g);
if(typeG == 2) {
if(binConnective == '^') {
return &leftArray;
} else if(binConnective == '>') {
return &leftArray;
}
} else if(typeG == 3) {
if(binConnective == 'v')
return &leftArray;
}
char temp[50];
for(int i = 0; i < strlen(leftArray); i++) {
temp[i+1] = leftArray[i];
}
temp[0] = '-';
char* lefttwo = &temp[0];
if(typeG == 2) {
if(binConnective == 'v') {
return lefttwo;
}
} else if(typeG == 3) {
if(binConnective == '>' || binConnective == '^') {
return lefttwo;
}
}
return "Hello";
}
char *secondexp(char *g) {
// char binaryConnective = bin(g);
// char* right = parttwo(g);
// char rightArray[50];
// int i = 0;
// for(i; i< strlen(right); i++) {
// rightArray[i+1] = right[i];
// }
// rightArray[i] = '\0';
// int typeG = type(g);
// if(type(g) == 2) {
// if(binaryConnective == '^') {
// return &rightArray;
// }
// } else if(type(g) == 3) {
// if(binaryConnective == 'v' || binaryConnective == '>') {
// return &rightArray;
// }
// }
return "Hello";
}
typedef struct tableau tableau;
\
\
struct tableau {
char *root;
tableau *left;
tableau *right;
tableau *parent;
int closedbranch;
};
int closed(tableau *t) {
return 0;
}
void complete(tableau *t) {
}
/*int main(int argc, const char * argv[])
{
printf("Hello, World!\n");
printf("%d \n", parse("p^q"));
printf("%d \n", type("p^q"));
printf("%c \n", bin("p^q"));
printf("%s\n", partone("p^q"));
printf("%s\n", parttwo("p^q"));
printf("%s\n", firstexp("p^q"));
printf("Simulation complete");
return 0;
}*/
File 2:
#include <stdio.h>
#include <string.h> /* for all the new-fangled string functions */
#include <stdlib.h> /* malloc, free, rand */
#include "yourfile.h"
int Fsize = 50;
int main()
{ /*input a string and check if its a propositional formula */
char *name = malloc(Fsize);
printf("Enter a formula:");
scanf("%s", name);
int p=parse(name);
switch(p)
{case(0): printf("not a formula");break;
case(1): printf("a proposition");break;
case(2): printf("a negated formula");break;
case(3): printf("a binary formula");break;
default: printf("what the f***!");
}
printf("\n");
if (p==3)
{
printf("the first part is %s and the second part is %s", partone(name), parttwo(name));
printf(" the binary connective is %c \n", bin(name));
}
int t =type(name);
switch(t)
{case(0):printf("I told you, not a formula");break;
case(1): printf("A literal");break;
case(2): printf("An alpha formula, ");break;
case(3): printf("A beta formula, ");break;
case(4): printf("Double negation");break;
default: printf("SOmewthing's wrong");
}
if(t==2) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
if(t==3) printf("first expansion fmla is %s, second expansion fmla is %s\n", firstexp(name), secondexp(name));
tableau tab;
tab.root = name;
tab.left=0;
tab.parent=0;
tab.right=0;
tab.closedbranch=0;
complete(&tab);/*expand the root node then recursively expand any child nodes */
if (closed(&tab)) printf("%s is not satisfiable", name);
else printf("%s is satisfiable", name);
return(0);
}
If you look at the first file, you'll see a method called * firstexp(char * g).
This method runs perfectly, but only if another method called * secondexp(char * g) is commented out.
If * secondexp(char * g) is commented out, then *firstexp runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is -(pvq), second expansion fmla is Hello
((pvq)>-p) is satisfiableProgram ended with exit code: 0
otherwise, if *secondexp is not commented out, it runs like this:
Enter a formula:((pvq)>-p)
a binary formula
the first part is (pvq) and the second part is -p the binary connective is >
A beta formula, first expansion fmla is \240L, second expansion fmla is (-
((pvq)>-p) is satisfiable. Program ended with exit code: 0
As you can see, the outputs are completely different despite the same input. Can someone explain what's going on here?
In the commented-out parts of secondexp and in parttwo, you return the address of a local variable, which you shouldn't do.
You seem to fill a lot of ad-hoc sized auxiliary arrays. These have the problem that they might overflow for larger expressions and also that you cannot return them unless you allocate them on the heap with malloc, which also means that you have to free them later.
At first glance, the strings you want to return are substrings or slices of the expression string. That means that the data for these strings is already there.
You could (safely) return pointers into that string. That is what, for example strchr and strstr do. If you are willing to modify the original string, you could also place null terminators '\0' after substrings. That's what strtok does, and it has the disadvantage that you lose the information at that place: If you string is a*b and you modify it to a\0b, you will not know which operator there was.
Another method is to create a struct that stores a slice as pointer into the string and a length:
struct slice {
const char *p;
int length;
};
You can then safely return slices of the original string without needing to worry about additional memory.
You can also use the standard functions in most cases, if you stick to the strn variants. When you print a slice, you can do so by specifying a field width in printf formats:
printf("Second part: '%.*s'\n", s->length, s->p);
In your parttwo() function you return the address of a local variable
return rightSide;
where rightSide is a pointer to a local variable.
It appears that your compiler gave you a warning about this which you solved by making a pointer to the local variabe arrayRight, that may confuse the compiler but the result will be the same, the data in arrayRight will no longer exist after the function returns.
You are doing the same all over your code, and even worse, in the secondexp() function you return a the address of a local variable taking it's address, you are not only returning the address to a local variabel, but also with a type that is not compatible with the return type of the function.
This is one of many probable issues that your code may have, but you need to start fixing that to continue with other possible problems.
Note: enable extra warnings when compiler and listen to them, don't try to fool the compiler unless you know exactly what you're doing.

code with double free or corruption

I've got a double free problem in my program. I know which pointer is double freed but I cant figure out when was it freed first.
here is the code of my function :
int spectrum_gen(char *shift_r, char *rec_poly, char *redun_poly,int spectrum_length)
{
char *seq = NULL,*l_shift = NULL,loop_shift[SIZE];
int current_weight,*spectrum = NULL,*spect_numb = NULL,length=1,spectrum_size=0;
int index,index2,temp,temp2,*temp3;
/* int *weights = NULL; */
int *encoded_w = NULL;
int min_length,min_weight = 1000;
int looping = 0;
int **spectrum_content = NULL;
int *seq_w;
int *weight_table = symbols_weight(Q);
int *weights = NULL;
spectrum= (int*) malloc(sizeof(int));
seq = (char*) malloc(sizeof(char));
l_shift = (char*) malloc(SIZE*sizeof(char*));
weights = (int*) malloc(sizeof(int));
encoded_w = (int*) malloc(sizeof(int));
spect_numb = (int*) malloc(sizeof(int));
spectrum_content = (int**) malloc(sizeof(int*));
spectrum_content[1] = (int*) malloc(sizeof(int));
seq_w = (int*) malloc(sizeof(int));
strcpy(seq,"1");
convert_to_real(seq,1);
while(length > 0)
{
/* show_word(seq,length);
show_word(shift_r,SIZE);
puts(""); */
if(length == 1)
{
set2zero(shift_r,SIZE);
current_weight = RTZ_weight(0,seq[0],shift_r,rec_poly,redun_poly,encoded_w,seq_w,weight_table);
*seq_w += seq_weight(seq,1,weight_table);
}
else
{
current_weight = RTZ_weight(weights[length-2],seq[length-1],shift_r,rec_poly,redun_poly,encoded_w,seq_w,weight_table);
*seq_w += seq_weight(seq,length,weight_table);
/* show_word(shift_r,SIZE);
show_word(loop_shift,SIZE); */
if(looping==1 && str_cmp(shift_r,loop_shift,SIZE))
{
puts("looping sequence!!");
free(spectrum);
spectrum = NULL;
free(encoded_w);
encoded_w = NULL;
free(spect_numb);
spect_numb = NULL;
free(spectrum_content);
spectrum_content = NULL;
free(weights);
weights = NULL;
return 1;
break;
}
if(*encoded_w==weights[length-2] && looping==0 && length>3)
{
str_cpy(loop_shift,shift_r,SIZE);
looping = 1;
}
if(*encoded_w != weights[length-2])
{
looping = 0;
}
}
weights = realloc(weights,length*sizeof(int));
weights[length-1] = *encoded_w;
l_shift = realloc(l_shift,length*sizeof(char));
l_shift[length-1] = shift_r[SIZE-1];
if((shift_r[0] != 0) && (*encoded_w < spectrum_length))
{
if((temp = index4(current_weight,spectrum,spectrum_size,1,0)) != (-1))
{
spect_numb[temp]++;
if((temp2 = index4(*seq_w,spectrum_content[temp],spectrum_content[temp][0],2,1)) != (-1))
{ spectrum_content[temp][temp2+1]++;
}
else
{
spectrum_content[temp][0] += 2;
spectrum_content[temp] = realloc(spectrum_content[temp],spectrum_content[temp][0]*sizeof(int));
spectrum_content[temp][spectrum_content[temp][0]-2] = *seq_w;
spectrum_content[temp][spectrum_content[temp][0]-1] = 1;
}
}
else
{
spectrum_size++;
spectrum = realloc(spectrum,spectrum_size*sizeof(int));
spect_numb = realloc(spect_numb,spectrum_size*sizeof(int));
/* spectrum content : creation of a new table to store the inputs with output of weight current_weight*/
spectrum_content = realloc(spectrum_content,spectrum_size*sizeof(int*));
spectrum_content[spectrum_size-1] = (int*) malloc(3*sizeof(int));
spectrum_content[spectrum_size-1][0] = 3;
spectrum_content[spectrum_size-1][1] = *seq_w;
spectrum_content[spectrum_size-1][2] = 1;
spectrum[spectrum_size-1] = current_weight;
spect_numb[spectrum_size-1] = 1;
}
}
if(seq_equal_zero(shift_r,SIZE) || (*encoded_w >= spectrum_length))
{
while((length>0) && (seq[length-1] == Q-1))
{
length--;
for(index=0;index<SIZE-1;index++)
shift_r[index] = shift_r[index+1];
shift_r[SIZE-1] = l_shift[length-1];
}
for(index=0;index<SIZE-1;index++)
shift_r[index] = shift_r[index+1];
shift_r[SIZE-1] = l_shift[length-2];
seq[length-1] += 1;
}
else
{
length++;
seq = realloc(seq,length*sizeof(char));
seq[length-1] = 0;
}
/* printf("%d\n%d\n",*encoded_w,current_weight);
getchar(); */
}
/* sort(spectrum,spect_numb,spectrum_content,spectrum_size);*/
puts("Debut du spectre de ce codeur :");
for(index=0;spectrum[index+1]<=spectrum_length;index++)
{
printf("( ");
for(index2=1;index2<spectrum_content[index][0]-2;index2+=2)
{
printf("%d*I^%d + ",spectrum_content[index][index2+1],spectrum_content[index][index2]);
}
printf("%d*I^%d",spectrum_content[index][spectrum_content[index][0]-1],spectrum_content[index][spectrum_content[index][0]-2]);
printf(" )*O^%d + ",spectrum[index]);
}
printf("( ");
for(index2=1;index2<spectrum_content[index][0]-2;index2+=2)
{
printf("%d*I^%d + ",spectrum_content[index][index2+1],spectrum_content[index][index2]);
}
printf("%d*I^%d",spectrum_content[index][spectrum_content[index][0]-1],spectrum_content[index][spectrum_content[index][0]-2]);
printf(")*O^%d",spectrum[index]);
puts("");
free(seq);
seq = NULL;
free(spectrum);
spectrum = NULL;
free(encoded_w);
encoded_w = NULL;
free(spect_numb);
spect_numb = NULL;
free(spectrum_content);
spectrum_content = NULL;
free(weights);
weights = NULL;
return 0;
}
that pointer is called seq.
It would be so cool if someone helps me with this :)
here are the two functions that handle that pointer
void convert_to_real(char *word,int end)
{
int index;
for(index=0;index<end;index++) word[index]-='0';
}
i dont think it may be a problem
the only other function that handles that pointer is :
int seq_weight(char *seq,int end,int *weight_table)
{
int index,weight = 0;
for(index=0;index<end;index++)
if(seq[index]>=0 && seq[index]<Q)
weight += weight_table[(int)seq[index]];
return weight;
}
and i dont think it would cause a problem neither. :(
It's great that you set the pointer value to null after you have free'd it. So make use of that fact, and check for null before you free it - that way you avoid the double delete. Then you don't have to hunt for the double deletion because you will be protected from it.

Segfault on fscanf

filenamelists is a struct with two file pointers. merge mergesorts these two fileptrs. I'm getting a segfault on the while(fscanf(filenamelist[0].file1, "%d", &chd) != EOF). I think its because I'm not implementing pthread correctly. Ive been trying to debug forever so any help would be appreciated. tempf is a file ptr to the mergesorted arrays. It is rewinded in the merge function itself.
for(i=0; i<size; i++)
{
if(argc==1)
{
char* tedious2 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
strcpy(tedious2,argv[i+1]);
filenamelist[i].file1 = fopen(strcat(tedious2,".sorted"),"r");
filenamelist[i].file2 = NULL;
filenamelist[i].alone = 1;
free(tedious2);
break;
}
else if(size-1 ==i && size%2 != 0)
{
char* tedious1 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
strcpy(tedious1,argv[i+1]);
filenamelist[i].file1 = fopen(strcat(tedious1,".sorted"),"r");
filenamelist[i].file2 = NULL;
filenamelist[i].alone = 1;
free(tedious1);
}
else
{
char* tedious3 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
strcpy(tedious3,argv[i+1]);
char* tedious4 = (char*) malloc((strlen(argv[i+2]+7))*sizeof(char));
strcpy(tedious4,argv[i+2]);
filenamelist[i].file1 = fopen(strcat(tedious3,".sorted"),"r");
filenamelist[i].file2 = fopen(strcat(tedious4,".sorted"),"r");
filenamelist[i].alone = 0;
free(tedious3);
free(tedious4);
}
}
// pthread_t* threadid2;
// threadid2 = (pthread_t*) malloc(sizeof(pthread_t)*(2*argc));
while(size>=0)
{
i = 0;
pthread_t* threadid2;
threadid2 = (pthread_t*) malloc(sizeof(pthread_t)*size);
for ( ; i<size;i++ )
{
pthread_create(&threadid2[i], NULL, merge, &filenamelist[i]);
}
i = 0;
for ( ; i<size; i++)
{
pthread_join(threadid2[i], tempf);
if (i%2 == 0)
{
filenamelist[i/2].file1 = tempf;
}
else
{
filenamelist[i/2].file2 = tempf;
}
}
zit=0;
truth = 0;
while(zit<z)
{
if(inputFiles[zit] == tempf)
truth = 1;
zit++;
}
if(truth != 1)
{
inputFiles[z] = tempf;
z++;
}
if(size==1)
size = 0;
else if (size % 2 == 0)
size = size/2;
else
size = (size/2)+1;
free(threadid2);
}
int chd = 0;
// if(0!=feof(tempf))
// rewind(tempf);
//rewind(filenamelist[0]->file1);
int finish = 0;
//printf("file 1:%p",tempf);
while(fscanf(filenamelist[0].file1, "%d", &chd) != EOF)
finish++;
rewind(filenamelist[0].file1);
int* finarr = (int*) malloc(finish*sizeof(int));
int xx =0;
for(;fscanf(filenamelist[0].file1, "%d", &chd) != EOF; xx++)
finarr[xx] = chd;
tempf is declared at start of func as FILE* tempf;
char* tedious2 = (char*) malloc((strlen(argv[i+1]+7))*sizeof(char));
Make that:
char *tedious2 = malloc( strlen(argv[i+1]) + strlen(".sorted") + 1 );

Resources