2

I'm new to pointers and I'm trying to implement a simple code, in which i read and write an array and I also search for the minimum element between two given indexes. For some reason the write() function prints large values (I'm guessing they are the locations in which values are stored). Also I receive a SIGSECV when I run the poz_minVal function. I know this is a nooby question, but any help will de much appreciated!

The code is as follows:

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

int read(int *v, FILE *f){
    int i,length;
    fscanf(f,"%d",&length);
    v = (int *)malloc(length*sizeof(int));
    for(i=0;i<length;++i)
        fscanf(f,"%d",v+i);
    return length;
}

void write(int *v, int length, FILE *g){
    int i;
    for(i=0;i<length;++i)
        fprintf(g,"%d ",*(v+i));
    fprintf(g,"\n\n");
}

int poz_valMin(int *v, int length,int left,int right){
    int k,mini = *v; //set mini as the 1st element in v
    for(k=left;k<right;++k)
        if(*(v+k) < mini)
            mini = *(v+k);
    return mini;
}

int main(){
    FILE *f = fopen("datein.txt","r");
    FILE *g = fopen("dateout.txt","w");
    int *v, n = read(v,f);
    write(v,n,g);
    fprintf("The minimum value between the indexes 2 and 4 is: %d.\n\n",poz_valMin(v,n,2,4));
    return 0;
}
16
  • Please show the input data. Commented Jan 27, 2017 at 11:20
  • which line ? where are the input datas? Commented Jan 27, 2017 at 11:22
  • 1
    You have made mistake with pointers !! :) Commented Jan 27, 2017 at 11:22
  • Also you forgot to free v. Commented Jan 27, 2017 at 11:23
  • 2
    Instead of *(v+i), it's easier and more idiomatic to write v[i]. Commented Jan 27, 2017 at 11:26

4 Answers 4

3

Whatever barak manos has said is right, but let me point another way of defining read function.

int * read(FILE *f){
   int *v,length;
   fscanf(f,"%d",&length);
   v = (int *)malloc(length*sizeof(int));
   for(i=0;i<length;++i)
       fscanf(f,"%d",v+i);
   return v;
}


and then in main you should just write v = read(f);
This looks clean and simplifies the understanding.

A tip :
Once you notice that write is producing garbage, you should have printed the array v, and you could have caught the mistake !!

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

4 Comments

@alk This implementation is kinda awsome, thanks a lot for the idea!
@MattB: It's prem ktiw's answer! I just corrected the grammar a bit.
@MattB The implementation is just a tweaking in your code only. And you can give a +1 to the answer as well :) Thanks to alk for the correction .
2

Function read should take int** v, and assign *v = ....

Changing an input argument inside a function has no effect on the value of that argument outside the function.

Comments

1
//int read(int *v, FILE *f) //<-- in this case v will be treated as local variable inside read() and not the parameter passed from main.
int read(int **v, FILE *f)
{
    int i,length;
    fscanf(f,"%d",&length);
    //v = (int *)malloc(length*sizeof(int));
    int *arr = (int *)malloc(length*sizeof(int));
    for(i=0;i<length;++i)
        //fscanf(f,"%d",v+i);
        fscanf(f,"%d",arr+i);

    *v = arr;  //now you are actually assigning the allocated memory to main::v
    return length;
}

read(&v,f);  //call read like this.

1 Comment

1

the following code:

  1. incorporates the comments to the question, except good variable naming
  2. cleanly compiles
  3. performs the desired operation
  4. performs appropriate error checking

You should get in the habit of having the main() function (in those files that have a main() function) as the first function listed, Then use the appropriate 'prototype' statements for each of the sub functions

Suggest using size_t for values that must never be negative.

#include <stdio.h>  // fopen(), fclose(),
#include <stdlib.h>

size_t read(       int **v, FILE *f);
void   write(      int *v, size_t length, FILE *g );
int    poz_valMin( int *v, int left, int right );


int main( void )
{
    FILE *f = fopen("datein.txt","r");
    if( !f )
    {
        perror( "fopen for read of datain.txt failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fopen successful

    FILE *g = fopen("dateout.txt","w");
    if( !g )
    {
        perror( "fopen for write to dataout.txt failed" );
        fclose( f ); // cleanup
        exit( EXIT_FAILURE );
    }

    // implied else, fopen for output successful

    int *v;
    size_t n = read(&v,f);

    write(v,n,g);
    fprintf( stdout,
             "The minimum value between the indexes 2 and 4 is: %d.\n\n",
             poz_valMin(v, 2, 4));

    free( v );
    fclose( f );
    fclose( g );
}



size_t read(int **v, FILE *f)
{
    //int i;
    size_t length;

    if( 1 != fscanf(f,"%lu",&length) )
    {
        perror( "fscanf failed" );
        exit( EXIT_FAILURE );
    }

    // implied else, fscanf successful

    *v = malloc(length*sizeof(int));
    if( !v )
    {
        perror( "malloc failed" );
        fclose( f );
        exit( EXIT_FAILURE );
    }

    // implied else, malloc successful

    for(size_t i=0; i<length; ++i)
    {
        if( 1 != fscanf(f,"%d",(*v)+i) )
        {
            perror( "fscanf for array values failed" );
            free( *v );
            fclose( f );
            exit( EXIT_FAILURE );
        }

        // implied else, fscanf successful
    }

    return length;
}


void write(int *v, size_t length, FILE *g)
{
    //int i;

    for( size_t i=0; i<length; ++i )
        fprintf(g,"%d ",*(v+i));

    fprintf(g,"\n\n");
}


int poz_valMin( int *v, int left, int right )
{
    int k;
    int mini = *v; //set mini as the 1st element in v

    for(k=left; k<right; ++k)
        if(*(v+k) < mini)
            mini = *(v+k);

    return mini;
}

Comments

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.