Passing struct-within-pointer-array-within-struct by address in C
I have a function which takes a pointer, polynomial to an instance of a struct called POLYNOMIAL. This contains an array of pointers to another struct, called TERM. TERM contains two ints.
This function is intended to modify one of the ints within TERM. I am trying to do so with the line:
polynomial->terms[i]->Coefficient *= scalar;
But this isn't working; while the function sees what I expect it to when I call
polynomial->terms[i]->Coefficient
,
the changes are apparently limited to the scope of the function. I've diagrammed out my best understanding of the memory to try and find the problem, to no avail.
EDIT: Polynomial definition:
typedef struct Polynomial {
TERM *terms[MAXPOLYTERMS];
int numTerms;
char Polynomialstring[MAXPOLYCHARS];
} POLYNOMIAL;
Term definition:
typedef struct Term {
int Coefficient;
int Exponent;
char Termstring[MAXTERMCHARS];
} TERM;`
Function:
void MultiplyPolynomial(POLYNOMIAL *po开发者_如何学JAVAlynomial, int scalar)
{
int numberofterms = polynomial->numTerms, i=0;
if(scalar == 0)
{FreePolynomial(polynomial);}
else
{
for(i=0;i<numberofterms;i++)
{polynomial->terms[i]->Coefficient *= scalar;}
}
return;
}
There isn't anything obviously wrong with the code you do show us, so the chances are that the problem is in the code you've not shown us. That's a fairly complex data structure to be managing; I wonder if you have a mistake in the code that loads it up. Perhaps you should show us the code that initializes and allocates the data, and the code that you use to print the data - plus the test program. It could be just a quadratic (3-term) polynomial; that's enough to be going on with.
I'd not be surprised to find that the trouble is in your allocation of terms
within a polynomial. You probably really want:
typedef struct Polynomial
{
TERM *terms;
int numTerms;
char Polynomialstring[MAXPOLYCHARS];
} POLYNOMIAL;
You can then allocate the correct number of terms with:
poly->terms = malloc(nterms * sizeof(*poly->terms));
poly->nterms = nterms;
You can use almost the same expressions as before to access terms:
poly->terms[i].Coefficient *= scalar;
Note the change from ->
to .
in the last part.
Error checking omitted for brevity and clarity.
It is likely you do not do MAXPOLYTERMS separate allocated assignments as is required with your existing data structure.
Version using simplified Polynomial structure
I've eliminated unused parts of the code (like the strings) to get to this version, which compiles clean under GCC 4.2.1 (using -std=c99 -Wall -Wextra
) on MacOS X 10.6.6 and runs clean under Valgrind 3.6.1.
#include <stdlib.h>
#include <stdio.h>
typedef struct Term
{
int Coefficient;
int Exponent;
} TERM;
typedef struct Polynomial
{
TERM *terms;
int numTerms;
} POLYNOMIAL;
static void FreePolynomial(POLYNOMIAL *poly)
{
free(poly->terms);
free(poly);
}
static void MultiplyPolynomial(POLYNOMIAL *polynomial, int scalar)
{
int numberofterms = polynomial->numTerms;
for (int i = 0; i < numberofterms; i++)
polynomial->terms[i].Coefficient *= scalar;
}
static POLYNOMIAL *allocPoly(int *array, int num)
{
POLYNOMIAL *poly = malloc(sizeof(*poly));
poly->terms = malloc(num * sizeof(*poly->terms));
for (int i = 0; i < num; i++)
{
poly->terms[i].Coefficient = array[2*i+0];
poly->terms[i].Exponent = array[2*i+1];
}
poly->numTerms = num;
return poly;
}
static void dumpPolynomial(FILE *fp, POLYNOMIAL *poly, const char *tag)
{
fprintf(fp, "Polynomial dump (%s): 0x%p\n", tag, poly);
if (poly != 0)
{
fprintf(fp, "Terms %d\n", poly->numTerms);
for (int i = 0; i < poly->numTerms; i++)
fprintf(fp, "%d: Coefficient %d, Exponent %d\n", i,
poly->terms[i].Coefficient, poly->terms[i].Exponent);
}
fflush(fp);
}
int main(void)
{
int coeffs[] = { 1, 0, 2, 1, 3, 2 };
POLYNOMIAL *poly = allocPoly(coeffs, 3);
dumpPolynomial(stdout, poly, "Before");
MultiplyPolynomial(poly, 4);
dumpPolynomial(stdout, poly, "After");
FreePolynomial(poly);
return 0;
}
Version using complicated Polynomial structure
This is using your original data structures. It to compiles clean and runs clean.
#include <stdlib.h>
#include <stdio.h>
enum { MAXPOLYTERMS = 5, MAXPOLYCHARS = 5, MAXTERMCHARS = 5 };
typedef struct Term {
int Coefficient;
int Exponent;
char Termstring[MAXTERMCHARS];
} TERM;
typedef struct Polynomial {
TERM *terms[MAXPOLYTERMS];
int numTerms;
char Polynomialstring[MAXPOLYCHARS];
} POLYNOMIAL;
static void FreePolynomial(POLYNOMIAL *poly)
{
for (int i = 0; i < poly->numTerms; i++)
free(poly->terms[i]);
free(poly);
}
static void MultiplyPolynomial(POLYNOMIAL *polynomial, int scalar)
{
int numberofterms = polynomial->numTerms, i=0;
if(scalar == 0)
{FreePolynomial(polynomial);}
else
{
for(i=0;i<numberofterms;i++)
{polynomial->terms[i]->Coefficient *= scalar;}
}
return;
}
static POLYNOMIAL *allocPoly(int *array, int num)
{
POLYNOMIAL *poly = malloc(sizeof(*poly));
for (int i = 0; i < num; i++)
{
poly->terms[i] = malloc(sizeof(TERM)); // backsliding
poly->terms[i]->Coefficient = array[2*i+0];
poly->terms[i]->Exponent = array[2*i+1];
poly->terms[i]->Termstring[0] = '\0';
}
poly->numTerms = num;
poly->Polynomialstring[0] = '\0';
return poly;
}
static void dumpPolynomial(FILE *fp, POLYNOMIAL *poly, const char *tag)
{
fprintf(fp, "Polynomial dump (%s): 0x%p\n", tag, poly);
if (poly != 0)
{
fprintf(fp, "Terms %d\n", poly->numTerms);
for (int i = 0; i < poly->numTerms; i++)
fprintf(fp, "%d: Coefficient %d, Exponent %d\n", i,
poly->terms[i]->Coefficient, poly->terms[i]->Exponent);
}
fflush(fp);
}
int main(void)
{
int coeffs[] = { 1, 0, 2, 1, 3, 2 };
POLYNOMIAL *poly = allocPoly(coeffs, 3);
dumpPolynomial(stdout, poly, "Before");
MultiplyPolynomial(poly, 4);
dumpPolynomial(stdout, poly, "After");
return 0;
}
精彩评论