0

So the goal of this code snippet is to read in numbers from a file that represents the coefficients of a polynomial. The amount of numbers is not known before hand. There is one "polynomial" per line. Example of the file I am reading below.

Polynomails.txt
1 2 0 0 5
7.0 0 0 0 -2.25 1.13

Currently main only checks that a filename was given and that it can be opened, then calls ReadPoly, shown below. BUFFSIZE is a defined to be 256 with a define statement in this file.

void ReadPoly(FILE* InputFile){
    polynomial poly;
    double complex *coef;
    char *p, *buffer;
    unsigned int terms;

    buffer = (char*) malloc(BUFFSIZE);

    while(fgets(buffer,BUFFSIZE,InputFile)){    
        coef = (double complex*) malloc(BUFFSIZE*sizeof(double complex));
        terms = 0;
        p = strtok(buffer, " ");
        while(NULL != p){
            coef[terms] = atof(p);
            terms++;
            p = strtok(NULL, " ");
        }
        coef = (double complex*) realloc(coef,(terms*sizeof(double complex)));
        printf("terms provided to init: %d\n",terms);
        createPoly(&poly,terms);
        poly.polyCoef = coef;       
        printf("terms in struct: %d\n",poly.nterms);
    }
    free(buffer);
}

And here is the createPoly function and the declaration of the poly struct.

typedef struct
{
unsigned int nterms;       /* number of terms */
double complex *polyCoef;  /* coefficients    */
} polynomial;


void createPoly(polynomial *p, unsigned int nterms){    
    double complex terms[nterms];   

    p = (polynomial*) malloc(sizeof(polynomial));

    p->nterms = nterms;
    p->polyCoef = terms;
    printf("In createPoly, nterms: %d\n",p->nterms);    
}

Now from what I can tell all of the numbers are being read in properly, but the nterms value in the structure is not working as expected. Here is the output when I run this. Its worth mentioning that even with the same file input, the "terms in struct" value is not always the same.

terms provided to init: 6
In createPoly, nterms: 6
terms in struct: 1075624960
terms provided to init: 5
In createPoly, nterms: 5
terms in struct: 1075624960

My only though is that the polyCoef field of the struct is somehow writing over the nterms field but without fixed sizes(which are not an option) I'm unsure of how to proceed.

Dave851
  • 5
  • 8
  • [Do not cast the result of malloc/calloc/realloc in C](http://stackoverflow.com/questions/605845/do-i-cast-the-result-of-malloc). – Paul R Apr 05 '15 at 15:15
  • `buffer = (char*) malloc(BUFFSIZE);` if BUFFSIZE is constant it would be better to use `char buffer[BUFFSIZE];` – Alex Díaz Apr 05 '15 at 15:17

3 Answers3

0

In your createPoly routine, you dynamically allocate a polynomial and set its nterms member, but you never return a pointer to the dynamically allocated structure. The poly.nterms which you print in ReadPoly is completely unrelated to that within createPoly. You are just printing some uninitialized memory, which is why you get that large, random-looking value.

One way around this is to pass a pointer to a pointer into createPoly, like this:

void createPoly(polynomial **p, unsigned int nterms) {    
  double complex terms[nterms];
  *p = malloc(sizeof(polynomial));
  /* ... */
}

Then in ReadPoly:

polynomial *poly;
/* ... */
createPoly(&poly, terms);

Another option:

polynomial *createPoly(unsigned int nterms) {
  polynomial *poly = malloc(sizeof(polynomial));
  /* ... */
  return poly;
}
Alex D
  • 29,755
  • 7
  • 80
  • 126
  • Well its handed a pointer p, which is where the new polynomial is allocated to. I can get to all of the polyCoef fields just fine, its only nterms that's giving me grief. – Dave851 Apr 05 '15 at 15:20
  • Yes, it's handed a pointer `p`, which you overwrite with a different pointer. Then you never pass back the dynamically allocated pointer. – Alex D Apr 05 '15 at 15:21
0

In the ReadPoly function, you declare poly as a stack variable, meaning the compiler already have allocated space for the structure on the stack.

Then in creatPoly you reassign the pointer to some other memory you manually allocate, loosing the original pointer passed to createPoly, and so the data you set in the structure is only set for that newly allocated structure, not in the original structure passed to the function. That also means that you have a memory leak as the pointer you assigned to in createPoly is lost once the function returns.

There are two solutions: Either don't allocate memory in createPoly, or have poly be a pointer in ReadPoly and then pass a pointer to the pointer as the argument to createPoly (to enumate pass by reference). I suggest the first solution.

Some programmer dude
  • 400,186
  • 35
  • 402
  • 621
0

Problem was my overwriting the pointer in the createPoly function, malloc'ing the memory outside of the createPoly function was a simple fix.

I ended up using the first suggestion of Joachim Pileborg, mainly because I'm still somewhat new to C and haven't played with pointers to pointers yet.

Dave851
  • 5
  • 8