1

I have the following code:`

#include <stdio.h>
#include <stdlib.h>

void load_from_file(int A[], int *n);

int main()
{
    int *A;
    A = (int*)malloc(0);
    int count = 0;
    int i;

    load_from_file(A, &count);

    for(i = 0; i < count; i++)
    {
        printf("A[%d]=%d ", i, A[i]);
        printf("\n");
        printf("&A[%d]=%p \n\n", i, &A[i]);
    }

    return 0;
}

void load_from_file(int A[], int *n)
{
    FILE* fp;
    int temp, i;

    fp = fopen("data.txt", "r");
    if (fp == NULL)
    {
        printf("error!!");
        exit (1);
    }

    fscanf(fp, "%d", &temp);
    *n = temp;

    A = (int*) realloc(A, temp * sizeof(int));
    if (*A == NULL)
    {
        printf("error realloc!!");
        exit(1);
    }

    for(i = 0; i < temp; i++)
    {
        fscanf(fp, "%d", &A[i]);
    }

    for(i = 0; i < temp; i++)
    {
        printf("A[%d]=%d ", i, A[i]);
        printf("\n");
        printf("&A[%d]=%p \n\n", i, &A[i]);
    }

    fclose(fp);
}

I'm trying to read a text file into an array. First line of the file has the number of elements of the array, and second line the numbers-elements. We create the array through realloc. But something is going wrong..... I have some patches, printing the address of array's elements.

But unfortunatelly they are different(not all the times) inside the function, and outside the function, although an array is passed by reference (as I think...)

Please, tell me where is the mistake, and how can I fix the problem.

Thanks in advance...

Dimitri

4
  • could you give me a bit of the data.txt file, a few samples? Commented Mar 18, 2014 at 20:12
  • 1
    You're passing a pointer to the function, but you need to pass a pointer to a pointer to the function so the function can modify the value in the calling code (main()), or return the pointer from the function. Commented Mar 18, 2014 at 20:15
  • for examle: 1st line: 3 (means 3 elements), that is n=3, create an array with 3 elements. 2nd line: 2 3 4. we should have A[0]=2, A[1]=3, A[2]=4. That happens inside the function, but outside the functions there are totally different values and different addressess... Commented Mar 18, 2014 at 20:15
  • thanks Jonathan, but please write some code....I've spend over an hour, and I cannot understand the problem.... Commented Mar 18, 2014 at 20:19

1 Answer 1

1

Call:

int *A = load_from_file(&count);

Function:

int *load_from_file(int *n)
{
    FILE* fp;
    int temp,i;
    int *A = 0;

    fp=fopen("data.txt","r");
    if (fp==NULL){fprintf(stderr, "error!!\n");exit (1);}

    fscanf(fp,"%d",&temp);
    *n=temp;
    A = (int*) realloc(A,temp * sizeof(int));
    if (A == NULL) {fprintf(stderr, "error realloc!!\n");exit(1);}
    for(i=0;i<temp;i++)
        fscanf(fp, "%d",&A[i]);
    for(i=0;i<temp;i++)
    {
        printf("A[%d]=%d ",i,A[i]);
        printf("\n");
        printf("&A[%d]=%p \n\n",i,&A[i]);
    }
    fclose(fp);
    return A;
}

This is a totally minimal set of changes; the code needs a lot more work. In particular, the fscanf() calls should be error checked. There's a subtle but important change in the allocation test: if (A == NULL) rather than the original if (*A == NULL).


With somewhat more complete error checking:

int *load_from_file(int *n)
{
    FILE *fp;
    int temp, i;
    int *A = 0;
    const char file[] = "data.txt";

    fp = fopen(file, "r");
    if (fp == NULL)
    {
        fprintf(stderr, "Failed to open file %s for reading\n", file);
        exit(1);
    }

    if (fscanf(fp, "%d", &temp) != 1)
    {
        fprintf(stderr, "Failed to read number of entries\n");
        exit(1);
    }
    *n = temp;
    A = (int *) realloc(A, temp * sizeof(int));
    if (A == NULL)
    {
        fprintf(stderr, "Failed to reallocate %zu bytes of memory\n",
                temp * sizeof(int));
        exit(1);
    }
    for (i = 0; i < temp; i++)
    {
        if (fscanf(fp, "%d", &A[i]) != 1)
        {
            fprintf(stderr, "Failed to read entry number %d\n", i);
            exit(1);
        }
    }
    for (i = 0; i < temp; i++)
        printf("A[%d]=%d: &A[%d]=%p\n", i, A[i], i, &A[i]);
    fclose(fp);
    return A;
}

I have a library of error reporting functions that I use which would reduce the error handling from 4 lines to 1 line per error. I strongly recommend creating and using such a library for yourself.

Sign up to request clarification or add additional context in comments.

2 Comments

thanks a lot my friend!! So you say that it's impossible to write a function like void readFromFile(int **A,int *next); ? Or it will be very error prone?
It would be possible to use the interface void readFromFile(int **A, int *next); but I generally prefer to return the pointer to passing in a pointer to pointer. In practice, it makes no major difference. You might consider int readFromFile(char const *filename, int **A, int *next); which passes the file name to the function and returns a status (0 for OK, other values to indicate failure), so you can test for success or failure rather than necessarily terminating the program as the code currently does. You can return a null pointer in my version of the code. Lots of possibilities…

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.