Im not really sure where my program has gone wrong and would be thankful for any help provided. It compiles and runs up until the first function is called then crashes however I have tried multiple ways to fix it such as different names, changing the return values, changing the prototype functions and changing the types from floats to int but nothing is working.

Here is the code:

#include <stdio.h>
#define Max 4
#define MAX 6


void main(void)
{
    FILE *openfilewrite;
    int i=0, j=0;
    float open, write, read;
    float a=0,b,c;
    float arr[Max][MAX], arr1[Max][MAX];
    float INITIALIZE(float arrr[Max][MAX] ), MULTIPLY(float arrr[Max][MAX], float p ), OPENFILEWRITES(), OPENFILEREAD(), WRITEARRAY(float arrr[Max][MAX] ), READARRAY();

    printf("Please enter the integer value you would like to store\n");
    scanf("%f", a);
    arr[i][j]=0;
    arr[i][j]=INITIALIZE(arr[Max][MAX]);
    printf("j");
    arr1[i][j]=MULTIPLY(arr[Max][MAX],a);
    printf("j");
    open=OPENFILEWRITES();

    write=WRITEARRAY(arr[Max][MAX]);

    read=READARRAY(arr[Max][MAX]);

}




float INITIALIZE(float x[Max][MAX])
{
    int i=0, j=0;

    for(i=0; i<4; i++)
    {
        for(j=0; j<6; j++)
        {
            x[i][j]=(i+j);
        }
    }   
    return(x[i][j]);
}

float MULTIPLY(float x[Max][MAX],float a)
{
    int i=0, j=0;

    for(i=0; i<Max; i++)
    {
        for(j=0; j<MAX; j++)
        {
            x[i][j]= a*(i+j);
        }
    }
    return(x[i][j]);
}

float OPENFILEWRITES()
{
    FILE *openfilewrite ;

    if((openfilewrite = fopen("outfile.nums", "w")) == NULL) 
    {                           /*beginning of the if statement*/
    printf("ERROR: file %s can not be opened!\n", "outfile.nums");
    exit();
    }   
    return(0);
}

float WRITEARRAY(float x[Max][MAX])
{
    FILE *openfilewrite ;
    int i=0, j=0;

    if((openfilewrite = fopen("outfile.nums", "w")) == NULL) 
    {                           /*beginning of the if statement*/
    printf("ERROR: file %s can not be opened!\n", "outfile.nums");
    exit();
    }   

    for(i=0; i<Max; i++)
    {
        for(j=0; j<MAX; j++)
        {
            fprintf(openfilewrite,"%f\n", x[i][j]);
        }
    }
    return(x[i][j]);
}

float OPENFILEREAD()
{
    FILE *openfilewrite ;

    if((openfilewrite = fopen("outfile.nums", "r")) == NULL) 
    {                           /*beginning of the if statement*/
    printf("ERROR: file %s can not be opened!\n", "outfile.nums");
    exit();
    }
    return(0);
}

float READARRAY(float x[Max][MAX])
{
    FILE *openfilewrite ;

    int i=0, j=0;

    if((openfilewrite = fopen("outfile.nums", "w")) == NULL) 
    {                           /*beginning of the if statement*/
    printf("ERROR: file %s can not be opened!\n", "outfile.nums");
    exit();
    }   
    for(i=0; i<Max; i++)
    {
        for(j=0; j<MAX; j++)
        {
            fscanf(openfilewrite,"%f", x[i][j]);
        }
    }
    return(0);
}

Dani AI

Generated

This crash is classic undefined behavior caused by several independent bugs. is right that returning x[i][j] after the loops is out-of-bounds, but there are other immediate causes that will make the program fail even before the first meaningful operation: a scanf call that omits the address, passing arr[Max][MAX] (an out-of-bounds element) to functions instead of the array, using fscanf without &, opening the read routine with "w" instead of "r", calling exit() with no argument, and using void main().

Apply these fixes in order (prioritized):

  • Use int main(void) for standard compliance.
  • Fix input: scanf("%f", &a); so the address is passed.
  • Pass the array itself to functions (e.g., INITIALIZE(arr);), not arr[Max][MAX].
  • Make array-fill functions return nothing (or return a status), do not return x[i][j] after loops.
  • Open files with the correct mode ("w" for writing, "r" for reading), check fopen results, and always fclose.
  • Use fscanf(fp, "%f", &x[i][j]); and fprintf(fp, "%f\n", x[i][j]); and verify return values.
  • Replace exit() with exit(EXIT_FAILURE) and include <stdlib.h>.
  • Put prototypes at file scope or define functions before main; compile with -Wall -Wextra -std=c11 to catch more issues.

Run the program under a debugger and valgrind (as suggested by ) to find invalid reads/writes and see the exact crash site. The working example posted by demonstrates these safer patterns (explicit checks, separate load/save, correct I/O and error handling) and is a good reference for restructuring the program.

Recommended Answers

All 5 Replies

One mistake I immediately saw (though it's probably not the only one and might not be what's causing your crash) is that you're returning x[i][j] on line 91, but i and j are equal to Max and MAX (horrible names by the way) after the loop, so that's an out of bounds access.

Beyond that try running your program through a debugger and/or valgrind to find out where a crashes, what values the variables have when it does and whether or not those values are what you expected, and where and when you might be accessing memory incorrectly.

It compiles and runs up until the first function is called then crashes

I'm surprised it compiles. What compiler are you using? Anyway, there are a number of problems with your code such that it would be faster to give you a good example instead of enumerate the existing issues.

So here is a program that reads numbers into a 2D array, multiplies them by a user provided multiplier, and saves the result to a file with optional echo to the standard output. Please ask questions as I'm sure you'll have at least one. Note that I've taken care to comment interesting or important things in anticipation of questions you might not be in a position yet to ask:

#include <stdio.h>
#include <stdlib.h> /* For EXIT_SUCCESS and EXIT_FAILURE */

#define ROWS 4
#define COLS 6

int FileLoad(FILE* in, double a[ROWS][COLS], int stdout_echo);
void FileSave(FILE* out, double a[ROWS][COLS], int stdout_echo);
void Multiply(double a[ROWS][COLS], double multiplier);
void FlushLine(FILE* in);

int main(void)
{
    FILE* fp = fopen("test.txt", "r+");
    double a[ROWS][COLS];
    double multiplier;
    int rc;

    /* Always check to see if the file opened successfully */
    if (!fp)
    {
        /* perror() also prints a useful system error for troubleshooting */
        perror("Error opening file");
        return EXIT_FAILURE;
    }

    if (!FileLoad(fp, a, 1))
    {
        fclose(fp); /* Don't forget to close the file! */
        return EXIT_FAILURE;
    }

    /* 
        Reset both the error state and file position. 
        This way we can safely switch to write mode.
    */
    clearerr(fp);
    rewind(fp);

    printf("Please enter a multiplier: ");
    fflush(stdout); /* This is needed because there's no newline in the prompt */

    /* scanf() returns the number of successful conversions */
    while ((rc = scanf("%lg", &multiplier)) != 1)
    {
        /* We'll assume that the error is due to bogus input and not something fatal */
        printf("Invalid input. Please enter a multiplier: ");
        fflush(stdout);

        /* Only flush the stream on a matching failure */
        if (rc != EOF)
        {
            clearerr(stdin); /* This is required as of 1999 */
            FlushLine(stdin); /* Clear out the bogus input */
        }
    }

    Multiply(a, multiplier);
    FileSave(fp, a, 1);

    fclose(fp); /* Don't forget to close the file, this is important! */

    return EXIT_SUCCESS;
}

int FileLoad(FILE* in, double a[ROWS][COLS], int stdout_echo)
{
    /*
        Assumptions:
            1) a's first dimension really is the size of ROWS.
    */
    int x, y;

    for (x = 0; x < ROWS; ++x)
    {
        for (y = 0; y < COLS; ++y)
        {
            if (fscanf(in, "%lg", &a[x][y]) != 1)
            {
                return 0;
            }

            if (stdout_echo)
            {
                printf("%g ", a[x][y]);
            }
        }

        if (stdout_echo)
        {
            putchar('\n');
        }
    }

    return 1;
}

void FileSave(FILE* out, double a[ROWS][COLS], int stdout_echo)
{
    /*
        Assumptions:
            1) a's first dimension really is the size of ROWS.
            2) a is properly and completely initialized.
    */
    int x, y;

    for (x = 0; x < ROWS; ++x)
    {
        for (y = 0; y < COLS; ++y)
        {
            fprintf(out, "%g ", a[x][y]);

            if (stdout_echo)
            {
                printf("%g ", a[x][y]);
            }
        }

        fputc('\n', out);

        if (stdout_echo)
        {
            putchar('\n');
        }
    }
}

void Multiply(double a[ROWS][COLS], double multiplier)
{
    /*
        Assumptions:
            1) a's first dimension really is the size of ROWS.
            2) a is properly and completely initialized.
    */
    int x, y;

    for (x = 0; x < ROWS; ++x)
    {
        for (y = 0; y < COLS; ++y)
        {
            a[x][y] *= multiplier;
        }
    }
}

void FlushLine(FILE* in)
{
    /*
        Assumptions:
            1) The stream contains at least one character.
    */
    int ch;

    do
    {
        ch = fgetc(in);
    }
    while (ch != '\n' && ch != EOF);

    clearerr(in); /* In case we reached EOF */
}

Hi deceptikon, what is the content of input file (in your case test.txt). It is nowhere mentioned and no Objective of the program is mentioned. and you have done everything what Sebass wants.
Hey Sebass, how can you build this code without error?? I used VS to build and got more than 20 error excluding warning.It has many build error as deceptikon mentioned.

Hi deceptikon, what is the content of input file (in your case test.txt). It is nowhere mentioned.

I used a super duper secret and obscure test case for the content of the file:

1 2 3 4 5 6
7 8 9 10 11 12
13 14 15 16 17 18
19 20 21 22 23 24

;)

Thanx Deceptiokon for your promptly reply and good comments for respective lines.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.