I'm trying to make an interpreter using C programming language, it works well, but when I try to add these two variables in the code, the program just crashes.
Fortunately, when I add the static keyword or I leave the variables as global in the program, the program doesn't crash.
Why does this happen ?
Here's the code:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <windows.h>
//If I leave the variables here the program doesn't crash
//int esMain = 0;
//int esEnd = 0;
int main(int argc, char** argv){
FILE *f;
f = fopen(argv[1], "r+");
if(f == NULL){
perror("Error: No se encuentra el archivo\nDescripcion");
exit(1);
}
if(ferror(f)){
printf("Archivo corrupto");
exit(1);
}
printf("\nEjecutando archivo: %s\n\n\n", argv[1]);
int esMain = 0;//These two variables makes the program to crash
int esEnd = 0;
//But if I add the static keyword in both variables the program works well.
char* str;
while(1){
fgets(str, 25, f);
if(strncmp(str, "MAIN:", 5) == 0){
esMain = 1;
}
if(strncmp(str, "END.", 4) == 0){
esEnd = 1;
}
if(feof(f) != 0){
if(esMain == 0){
printf("No existe el parametro main, cierre por no tener el parametro main (poner MAIN: ENCIMA)");
exit(1);
}
if(esEnd == 0){
printf("No existe el parametro end, cierre por no tener el parametro main (poner END. ENCIMA)");
exit(1);
}
break;
}
}
rewind(f);
while(1){
fgets(str, 500, f);
if(strncmp(str, "print ", 6) == 0){
printf(str + 6);
}
if(strncmp(str, "msg", 3) == 0){
if(strstr(str + 4, "check")){
MessageBox(HWND_DESKTOP, str + 10, "Check", MB_ICONINFORMATION);
}
if(strstr(str + 4, "error")){
MessageBox(HWND_DESKTOP, str + 10, "Error", MB_ICONERROR);
}
}
if(strncmp(str, "pause", 5) == 0){
getch();
}
if(feof(f) != 0){
break;
}
}
printf("\n\n\nEND EXECUTION");
fclose(f);
return 0;
}
The char* str; declaration is probably what is breaking your code. When you declare it as global it is stored in a different place in memory than if you declare it inside a function.
You got lucky to have your program working with it as global variable. Since you haven't reserved any place in memory, the variable is accessing some memory that it shouldn't (undefined behavior). Lucky might not be the best word to describe because due to t his undefined behavior you might think that your program is working correctly, which is not (If it had crashed you would be 100% that there were errors).
What you can do to fix that is one of the following:
allocate it dynamically: char *str = (char*)malloc(sizeof(char)*25);
change it to br an array: char str[25];
point to an existing array: char arr[25]; char *str = arr;
Related
I'm having problems while reading a file -again.
Here's my code:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct camion {
int data[3];
int numeropacchi;
char *hubprovenienza[100];
_Bool iseccezionale;
};
int main(void) {
struct camion **listacamion = malloc(sizeof(struct camion * ));
listacamion[0] = calloc(1, sizeof(struct camion));
int numerocamion = 0;
//importazione
FILE *input = fopen("info.txt", "r");
if (input != NULL) {
char *temp = calloc(100, sizeof(char));
for (int i = 0; true; i++) {
//1, 2, 3
fscanf(input, "%d - %d - %d",
&listacamion[i]->data[0],
&listacamion[i]->data[1],
&listacamion[i]->data[2]);
printf("ORA %d-%d-%d\n",
listacamion[i]->data[0],
listacamion[i]->data[1],
listacamion[i]->data[2]);
fscanf(input, "%d", &listacamion[i]->numeropacchi);
printf("NUMERO PACCHI %d\n", listacamion[i]->numeropacchi);
if (fscanf(input, "%s", listacamion[i]->hubprovenienza) == EOF) {
listacamion[i]->iseccezionale = false;
break;
}
printf("HUB PROVENIENZA %s\n", listacamion[i]->hubprovenienza);
//4
char eccezionale;
long i_senoneccezionale = ftell(input);
if (fscanf(input, "%s", temp) == EOF)
break;
else { //if not EOF alloc mem for the next truck
listacamion = realloc(listacamion, sizeof(struct camion *) * (i + 1));
listacamion[i + 1] = calloc(1, sizeof(struct camion))
numerocamion++;
printf("RIALLOCATA!\n");
}
if (temp[0] == 'E') //if 'E' is there, bool is true
listacamion[i]->iseccezionale = true;
else {
//otherwise go back to the saved pointer
listacamion[i]->iseccezionale = false;
fseek(input, i_senoneccezionale, SEEK_SET);
}
//set temp to zero;
free(temp);
temp = calloc(100, sizeof(char));
//---
printf("YES OR NO %d\n\n", listacamion[i]->iseccezionale);
}
}
//---
return 0;
}
Here's the input file I use:
22 - 03 - 2020
39
Bergamo
E
30 - 05 - 2021
90
Napoli
19 - 02 - 2022
132
Bari
21 - 03 - 2022
1721
Modena
E
I've got 3 or 4 lines per camion (truck) in my file, depending on whether the load is oversized or not (if it is, then an 'E' is put, otherwise the line in the file doesn't exist). So the end of the file could be detected either at the third fscanf or the fourth, but I'm not sure fscanf works this way... The issue is that the loop is correctly executed 3 times out of 4 (I've got the info of 4 trucks), then I get a segmentation fault, so I assumed that the problem might be an inadequate detection of the end of the file. I've tried other options - feof for example - but they weren't useful, and I can only find examples of a fscanf used as a condition, while my condition is just a true because I have different fscanfs...
Here's my output:
ORA 22-3-2020
NUMERO PACCHI 39
HUB PROVENIENZA Bergamo
RIALLOCATA!
YES OR NO 1
ORA 30-5-2021
NUMERO PACCHI 90
HUB PROVENIENZA Napoli
RIALLOCATA!
YES OR NO 0
ORA 19-2-2022
NUMERO PACCHI 132
HUB PROVENIENZA Bari
RIALLOCATA!
--------------------------------
Process exited after 0.4117 seconds with return value 3221226356
You should test the return value of every call to fscanf(): fscanf returns the number of successful conversions. A return value different from the number of conversions requested is an indication of invalid or missing input. Both must be handled to avoid undefined behavior.
fscanf(input, "%s", temp) is risky: a word longer than 99 bytes will cause a buffer overflow. You should write fscanf(input, "%99s", temp)
Here is a modified version using an array of structures instead of an array of pointers:
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct camion {
int data[3];
int numeropacchi;
char *hubprovenienza[100];
_Bool iseccezionale;
};
int main() {
struct camion *listacamion = NULL;
struct camion cam;
char ebuf[2];
int numerocamion = 0;
//importazione
FILE *input = fopen("info.txt", "r");
if (input != NULL) {
while (fscanf(input, "%d - %d - %d\n%d\n%99s",
&cam.data[0], &cam.data[1], &cam.data[2],
&cam.numeropacchi,
cam.hubprovenienza) == 5) {
cam.iseccezionale = false;
if (fscanf(input, " %1[E]", ebuf) == 1)
cam.iseccezionale = true;
printf("ORA %d-%d-%d\n"
"NUMERO PACCHI %d\n"
"HUB PROVENIENZA %s\n"
"YES OR NO %d\n\n",
cam.data[0], cam.data[1], cam.data[2]);
cam.numeropacchi,
cam.hubprovenienza,
cam.iseccezionale);
// if new truck, append to array
listacamion = realloc(listacamion, sizeof(*listacamion) * (numerocamion + 1));
listacamion[numerocamion] = cam;
numerocamion++;
printf("RIALLOCATA!\n");
}
}
return 0;
}
Check the return value of every call to scanf. You can refactor your code to make it simpler. Try something like:
#include <ctype.h>
#include <stdlib.h>
#include <stdio.h>
#include <unistd.h>
struct camion {
int data[3];
int numeropacchi;
char hubprovenienza[100];
_Bool iseccezionale;
};
int
get_record(FILE *fp, struct camion *c)
{
/* Read up to one record from the file. Return 1 on success. */
if( 3 != fscanf(fp, "%d -%d -%d", c->data, c->data + 1, c->data + 2) ){
return 0;
}
if( 1 != fscanf(fp, "%d", &c->numeropacchi) ){
return 0;
}
if( 1 != fscanf(fp, "%99s", c->hubprovenienza) ){
return 0;
}
int k;
while( ( k = fgetc(fp)) != EOF && isspace(k) ){
;
}
if( k == 'E' ){
c->iseccezionale = 1;
} else {
c->iseccezionale = 0;
ungetc(k, fp);
}
return 1;
}
int
main(int argc, char **argv)
{
struct camion c;
while( get_record(stdin, &c) ){
printf(
"%s is %soversized\n",
c.hubprovenienza,
c.iseccezionale ? "" : "not "
);
}
return 0;
}
Okay, this morning I've tried again and now it's working. Thanks to your comments I've paid more attention to the fscanf return value; I've also realized that I could get an EOF from either the 1st line per truck or the 4th one, not 3rd and 4th.
I didn't know whether to delete this question or what... so I've decided to post the code that worked for me just in case it might turn useful to some C beginners like me in the future because it contains a couple of things I wish I knew before. I'm also quite sure there's a faster way to do so, but who knows...
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
struct camion {
int data[3];
int numeropacchi;
char* hubprovenienza[100];
_Bool iseccezionale;
};
int main(void) {
struct camion** listacamion=malloc(sizeof(struct camion*));
listacamion[0]=calloc(1, sizeof(struct camion));
int numerocamion=0;
//importazione
FILE* input=fopen("info.txt", "r");
if(input!=NULL) {
char* temp=calloc(100, sizeof(char));
_Bool primavolta=true;
for(int i=0; true; i++) {
int fs1, fs4;
int temp1, temp2, temp3;
//1
if((fs1=fscanf(input, "%d - %d - %d", &temp1, &temp2, &temp3) == EOF))
break;
else {
numerocamion++;
if(primavolta) {
primavolta=false;
listacamion[i]->data[0]=temp1;
listacamion[i]->data[1]=temp2;
listacamion[i]->data[2]=temp3;
}
else {
//EVENTUALE RIALLOCAZIONE
listacamion=realloc(listacamion, sizeof(struct camion*)*(i+1));
listacamion[i]=calloc(1, sizeof(struct camion));
//---
listacamion[i]->data[0]=temp1;
listacamion[i]->data[1]=temp2;
listacamion[i]->data[2]=temp3;
}
}
//2
fscanf(input, "%d", &listacamion[i]->numeropacchi);
//3
fscanf(input, "%s", listacamion[i]->hubprovenienza);
//4
char eccezionale;
long i_senoneccezionale=ftell(input);
if((fs4=fscanf(input, "%s", temp)) == EOF) {//se è la fine del file...
listacamion[i]->iseccezionale=false;
free(temp);
break;
}
else {
if(temp[0]=='E') //se esiste il carattere 'E' - e quindi la quarta riga ESISTE - assegna il valore positivo alla booleana
listacamion[i]->iseccezionale=true;
else { /*se invece NON esiste il carattere 'E', ripristina il puntatore al file alla stessa riga che avrebbe dovuto contenere la 'E',
così che questo non vada perso per la prossima chiamata a scanf per la prima riga di ciascun camion, quella contenente la data*/
listacamion[i]->iseccezionale=false;
fseek(input, i_senoneccezionale, SEEK_SET);
}
}
//ripristina memoria per temp;
free(temp);
temp=calloc(100, sizeof(char));
//---
}
}
//---
//output
for(int i=0; i<numerocamion; i++) {
printf("%d-%d-%d %d %s %d\n", listacamion[i]->data[0], listacamion[i]->data[1], listacamion[i]->data[2], listacamion[i]->numeropacchi, listacamion[i]->hubprovenienza, listacamion[i]->iseccezionale);
}
return 0;
}
I've gotta do a shell simulator in C where some commands are mandatory, I'm placing the code here
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <errno.h>
#include <sys/wait.h>
#include <string.h>
#define ARRAYMAX 512
char *entrada = NULL;
size_t linha_tam = 0;
int i = 0;
char* token;
char* array[ARRAYMAX];
void help(){
printf("SHELL DESENVOLVIDA POR:\n ADERBAL NEVES CALMETO JÚNIOR\n GUILHERME DE CASTRO PAOLUCCI PAIVA\n");
printf("PARA SAIR DIGITE q\n");
}
void tokens(void *ent){
token = strtok(ent, "\n ");
while(token != NULL){
array[i++] = token;
token = strtok(NULL, "\n ");
}
array[i] = NULL;
}
void exec(){
int *a;
int pid = fork();
if(pid != 0){
waitpid(-1, a, 0);
}else{
if(execvp(array[0], array) == -1){
printf("%s", array[0]);
perror("Comando inválido");
}
}
}
int main(){
printf("Seja bem-vindo!\nDigite h para ajuda\n");
while(1){
printf(">");
getline(&entrada, &linha_tam, stdin);
if(strcmp(entrada, "\n") == 0){
printf("Insira um comando\n");
continue;
}
tokens(entrada);
if(strcmp(array[0], "q") == 0){
return 0;
}else if(strcmp(array[0], "h") == 0){
help();
continue;
}else{
exec();
printf("%s", array[0]);
}
}
}
the issue is, if I try to call "ls" right after starting the program, it works fine, but when I try to call "help" then "ls", the program crashes saying
ls: cannot access 'ls': no such file or directory
that's a error native from the lib, not written by me
I've tried to put some kinds of prints right on the "else" that comes first on the "ls" function but it's not printed, so, I've got no idea of what's happening
Move the global i variable to the local function tokens. As you never reset it to 0, you add more and more entries in array.
void tokens(void *ent){
int i = 0;
token = strtok(ent, "\n ");
while(token != NULL){
array[i++] = token;
token = strtok(NULL, "\n ");
}
array[i] = NULL;
}
There are a lot of issues (per comments) but the easiest solution for the question asked is to change the variable i from global to a (loop) local scope in tokens(). This also also eliminates the global token variable. Unrelated but I also added bounds check for array:
void tokens(char *ent) {
for(int i = 0; i < ARRAYMAX; i++) {
array[i] = strtok(i ? NULL : ent, "\n ");
if(!array[i]) break;
}
array[ARRAYMAX - 1] = NULL;
}
I'm trying to implement a function that gets every line from a file and prints it. For some reason, when running it I get a segmentation fault sometimes, sometimes it just runs fine, sometimes it exits with a incorrect checksum for freed object. I don't know which pointer is not being freed/modified after freeing it, can I get some clue?
The variable BUFFER_SIZE is defined from the keyboard, where I compile with the flags gcc -Wall -Werror -Wextra -D BUFFER_SIZE=23 get_next_line.c main.c
#include <string.h>
#include <stdlib.h>
#include <sys/types.h>
char *ft_strjoin(char const *s1, char const *s2)
{
char *s;
int p;
int p2;
if (s1 == NULL || s2 == NULL)
return (NULL);
s = malloc(strlen(s1) + strlen(s2) + 1);
if (s == NULL)
return (NULL);
p = 0;
while (s1[p])
{
s[p] = s1[p];
p++;
}
p2 = 0;
while (s2[p2])
{
s[p] = s2[p2];
p++;
p2++;
}
s[p] = '\0';
return (s);
}
char *ft_newstatic(char *aux, char *l, char **line)
{
char *temp;
int leng;
leng = strlen(l);
temp = malloc(leng + 1);
strlcat(temp, l, strlen(temp) + (leng - strlen(aux)) + 1);
*line = strdup(temp);
free(temp);
l = NULL;
l = strdup(&aux[1]);
return (l);
}
int get_next_line(int fd, char **line)
{
static char *stc_line;
char *buffer;
ssize_t nbytes;
char *aux;
stc_line = (!stc_line) ? strdup("") : stc_line;
buffer = malloc(BUFFER_SIZE + 1);
if (!buffer || fd <= 0 || BUFFER_SIZE <= 0 || !line)
return (-1);
while ((nbytes = read(fd, buffer, BUFFER_SIZE)) > 0)
{
buffer[nbytes] = '\0';
stc_line = ft_strjoin(stc_line, buffer);
if ((aux = strchr(stc_line, '\n')) != NULL)
{
//free(buffer);
return (((stc_line = ft_newstatic(aux, stc_line, line)) != NULL) ? 1 : 1);
}
}
if (nbytes < 0)
return (-1);
if ((aux = strchr(stc_line, '\n')) != NULL)
{
//free(buffer);
return (((stc_line = ft_newstatic(aux, stc_line, line)) != NULL) ? 1 : 1);
}
*line = strdup(stc_line);
stc_line = NULL;
free(buffer);
return (0);
}
If I remove both free(buffer) before returning ft_newstatic I get better results (less running time and not as many seg faults), but if I remove
stc_line = NULL;
free(stc_line);
I get weird output again:
2- archivo: texto.txt
[Return: 1] Line #124458: En un lugar de la mancha
[Return: 1] Line #124459: de cuyo nombre no quiero acordarme
[Return: 1] Line #124460: habia un hidalgo de los de lanza en astillero
[Return: 1] Line #124461: adarga antigua
[Return: 1] Line #124462: rocín flaco
[Return: 0] Line #124463: y galgo corredor.
End of file
3- archivo: texto2.txt
[Return: 1] Line #124464: y galgo corredor.linea 1
[Return: 1] Line #124465: linea 2
[Return: 1] Line #124466: linea 3
[Return: 0] Line #124467: linea 4
End of file
This is the main() that I use
#include <sys/types.h>
int get_next_line(int fd, char **line);
int main(int argc, char **argv)
{
int fd;
int ret;
int line;
char *buff;
int i;
line = 0;
if (argc > 1)
{
i = 0;
while (++i < argc)
{
fd = open(argv[i], O_RDONLY);
printf("%d- archivo: %s\n",i, argv[i]);
while ((ret = get_next_line(fd, &buff)) > 0)
{
printf("[Return: %d] Line #%d: %s\n", ret, ++line, buff);
free(buff);
}
printf("[Return: %d] Line #%d: %s\n", ret, ++line, buff);
if (ret == -1)
printf("-----------\nError\n");
else if (ret == 0)
printf("-----------\nEnd of file\n");
free(buff);
}
}
if (argc == 1)
{
while ((ret = get_next_line(0, &buff)) > 0)
printf("[Return: %d] Line #%d: %s\n", ret, ++line, buff);
if (ret == -1)
printf("-----------\nError\n");
else if (ret == 0)
printf("-----------\nEnd of stdin\n");
free(buff);
close(fd);
}
return (0);
}
temp = malloc(leng + 1);
strlcat(temp, l, strlen(temp) + (leng - strlen(aux)) + 1);
This is clearly wrong. The memory allocated by malloc contains garbage, so calling strlen on it makes no sense, and trying to use strlcat to append to it will break horribly. For instance, it is likely that the space you allocated doesn't contain a trailing nul byte, in which case strlen(temp) will return a number potentially much larger than leng+1, and strlcat may therefore write beyond the memory allocated. Or, strlen(temp) may simply segfault.
(I found this using valgrind, and then noticed that user3629249 also noticed the bug in a comment. I strongly recommend that you learn to use valgrind or a similar tool before proceeding any further with C.)
I cannot tell from your code what this function is supposed to do; it has an uninformative name and no comments. But I think you should first specify carefully its intended behavior, and then rewrite it.
As another note, you have a serious memory leak in main in the argc == 1 case:
while ((ret = get_next_line(0, &buff)) > 0)
printf("[Return: %d] Line #%d: %s\n", ret, ++line, buff);
/* ... */
free(buff);
Additional space is allocated for every line, and never freed. Only the last one is freed (outside the loop). When I ran your program, it used several gigabytes of memory for a modestly sized input file.
There are several other memory leaks in get_next_line where you use strdup to allocate strings that you never free.
I'm programming a spellchecker for an class assignment. The first step is to load a list separated by "\n" in a "dict" (that actually is a char** dict_main).
The procedure to load the dict is the next:
void dict_load(char *fname){
FILE *loaded_file = fopen(fname, "r");
char **aux = NULL;
int a = 0;
char word[MAX_WORD_SIZE];
//Checks whether fname was successfully loaded or not
if(loaded_file == NULL){
perror("Could not load dict\n");
exit(1);
} else {
while(fgets(word, MAX_WORD_SIZE, loaded_file) != NULL){
main_size++;
while(aux == NULL){
//To ensure that aux is not NULL
aux = realloc(dict_main, main_size);
}
dict_main = aux;
aux = NULL;
//Allocs space enough to store word
dict_main[main_size-1] = calloc(MAX_WORD_SIZE, sizeof(char));
strcpy(dict_main[main_size-1], word);
}
}
//Just for debbuging, prints each string in dict_main
for(a = 0; a<main_size; a++){
fprintf(stdout, "%s", dict_main[a]);
}
fclose(loaded_file);
}
This seems to work when I run it normaly, but when I use valgrind, I get a segfault when it tries to printf the strings.
This is the only procedure that runs in the program, this is main:
int main(int argc, char **argv){
char *dict;
//int i;
if (argc < 2)
{
printf("spellchecker.c: nro de argumentos erroneo. Deben ser <documento> [<diccionario>].\n");
return (1);
}
dict = (argc >=3) ? argv[2] : "dict.txt";
dict_main = calloc(main_size, sizeof(char*));
dict_load(dict);
free(dict_main);
printf("El documento %s ha sido procesado. Resultados en out.txt\n", argv[1]);
Is there something I'm missing and gets me that SegFault when I run it with valgrind?
}
I would really love some debugging help in this one. I've been working on this since the morning and its 4am. (I'm suppose to deliver this in 7 hours [11am])
Everything in main.c works but when I create some child processes to run compute.c's compiled file with execl it doesnt do it and sends an error of "Bad Address".
I've attached 3 pastebin links with main.c and compute.c and a txt file containing the tables I mention below.
The program is suppose to read 2 tables with integers from a file called pinakes.txt and then by using POSIX's shared memory API to place those tables in shared memory and create processes to calculate a 'row * column' sum from them and place that sum in another table.
sum += A[row][i] * B[i][column] = C[row][column]
Everything until the line below from main.c should work properly (I debugged it numerous times).
ppid = getpid();
main.c http://pastebin.com/iMCefaLZ
compute.c http://pastebin.com/Ejp214Up
pinakes.txt http://pastebin.com/h8yKXFvv
compile and then run
./main pinakes.txt
main.c
188 lines of code
#include <stdio.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/wait.h>
#include <signal.h>
#include <stdlib.h>
#include <ctype.h>
#include <string.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <errno.h>
int pinA_X = 0, pinA_Y = 0, pinB_X=0, pinB_Y=0;
int pinA[10][10], pinB[10][10], pinC[10][10];
main(int argc, char *argv[]){
int pid, ppid;
FILE *stream;
// general variables
int i, c, j, rc, converted, lines = 0;
//flags
int flagV=0, flagW=0, flagX=0, flagY=0, flagZ=0;
//shared memory
int dumpedArray[101];
int size = sizeof(dumpedArray);
int sid1 = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
int sid2 = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
int sid3 = shmget(IPC_PRIVATE, size, SHM_R | SHM_W);
int* shared_A = (int*) shmat(sid1, NULL, 0);
int* shared_B = (int*) shmat(sid2, NULL, 0);
int* shared_C = (int*) shmat(sid3, NULL, 0);
if(argc!=2){
printf("wrong number of arguments\n");
return -1;
}else{
stream = fopen(argv[1] , "r");
while((c = getc(stream))!= EOF){
if(flagZ == 0){
if(flagX == 1){pinA_X = c - 48;flagX = 0;}
if(c == 88){flagX = 1;}
if(flagY == 1){pinA_Y = c - 48;flagY = 0;}
if(c == 89){flagY = 1;}
if(c == 90){flagZ = 1;}
}else if(flagZ == 1){
if(flagX == 1){pinB_X = c - 48;flagX = 0;}
if(c == 88){flagX = 1;}
if(flagY == 1){pinB_Y = c - 48;flagY = 0;}
if(c == 89){flagY = 1;}
}
}
fclose(stream);
printf("pinA[%d][%d] * pinB[%d][%d] = C[%d][%d]\n\n", pinA_X, pinA_Y, pinB_X, pinB_Y, pinA_X, pinB_Y);
// get A
stream = fopen(argv[1] , "r");
i=0;j=0;
while((c = getc(stream))!= EOF){
if(i <= pinA_X && j <= pinA_Y){
if(flagW == 0){
if(c == 87){
flagW = 1;
}
}else{
if(c > 47 && c < 58){
pinA[i][j] = c - 48;
j++;
}
if(c == 13){
j=0;
i++;
}
}
}
}
fclose(stream);
// get B
stream = fopen(argv[1] , "r");
i=0;j=0;
while((c = getc(stream))!= EOF){
if(i <= pinB_X && j <= pinB_Y){
if(flagV == 0){
if(c == 86){
flagV = 1;
}
}else{
if(c > 47 && c < 58){
pinB[i][j] = c - 48;
j++;
}
if(c == 13){
j=0;
i++;
}
}
}
}
fclose(stream);
// print A
printf("A={\n");
for(j=0; j<pinA_X;j++){
for(i=0;i<pinA_Y;i++){
printf(" %d", pinA[j][i]);
}
printf("\n");
}
printf("}\n\n");
// print B
printf("B={\n");
for(j=0; j<pinB_X;j++){
for(i=0;i<pinB_Y;i++){
printf(" %d", pinB[j][i]);
}
printf("\n");
}
printf("}\n");
// Save pinA to shared Memory
converted = 0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
converted = (i * 10) + j;
shared_A[converted] = pinA[i][j];
}
}
// Save pinA to shared Memory
converted = 0;
for(i=0;i<10;i++){
for(j=0;j<10;j++){
converted = (i * 10) + j;
shared_B[converted] = pinB[i][j];
}
}
// Push size of arrays in shared memory
shared_A[100] = pinA_X;
shared_A[101] = pinA_Y;
shared_B[100] = pinB_X;
shared_B[101] = pinB_Y;
ppid = getpid();
for(i=0; i<pinA_X; i++){
for(j=0; j<pinB_Y; j++){
if(ppid == getpid()){
pid = fork();
if(pid==0){
if(execl("./compute", "compute", i, j, sid1, sid2, sid3, NULL) == -1){
printf("error exec\n");
printf("Error opening file: %s\n", strerror(errno));
};
}else if(pid<0){
printf("\nDen egine h fork!\n");
}else{
wait(0);
}
}
}
}
//print C
converted = 0;
printf("C={\n");
for(i=0;i<10;i++){
for(j=0;j<10;j++){
converted = (i * 10) + j;
pinC[i][j] = shared_C[converted];
printf(" %d", pinC[i][j]);
}
printf("\n");
}
printf("}\n");
}
}
Neither compute.c nor pintakes.txt is directly relevant to answering this question.
The bad address problem arises because you run:
for(i=0; i<pinA_X; i++){
for(j=0; j<pinB_Y; j++){
if(ppid == getpid()){
pid = fork();
if(pid==0){
if(execl("./compute", "compute", i, j, sid1, sid2, sid3, NULL) == -1){
The arguments to execl() must be strings; i and j are manifestly not strings (and sid1, sid2 and sid3 are the identifiers for three chunks of shared memory).
Convert those values to strings and try again.
Your program creates the shared memory with IPC_PRIVATE, so your code in compute.c (which is executed via execl() is going to be hard to make work. You may get away with transferring the shared memory IDs like that; I'm not sure.
I think I'd be using a single shared memory segment.
It also looked like your reading code is going to read the same data into the two arrays - but I may have been misreading it.
Finally, your PasteBin examples expire in 23 hours. That limits the usefulness of your question. You should really transfer the data into the question - with, I suggest, no tabs and tabstops set at 4 rather than 8. (Or use more functions to prevent such deep indentation.)
You are passing ints to execl, those should all be 0-terminated strings. Also, the final NULL must be cast to Char*.