In the following code, the result is ok, but the code will be crash when executing finish, and increase one error: Heap corruption detected, the free list is damaged at 0x600000008f50
int *mergeSort(int *a,int count) {
int leftCount = count / 2;
int rightCount = count - leftCount;
int *leftData = getData(a, 0, leftCount);
int *rightData = getData(a, leftCount, count);
int *sortedLeftData = mergeSort(leftData, leftCount);
int *sortedRightData = mergeSort(rightData, rightCount);
int *resultData = mergeData(sortedLeftData, sortedRightData, leftCount,
rightCount);
return resultData;
}
int *getData(int *a,int from, int to) {
if (from > to) { return nil; }
int *res = malloc(to - from + 1);
for (int index = from; index < to; index ++) {
int value = a[index];
res[index-from] = value;
}
return res;
}
int *mergeData(int *a, int *b, int acount, int bcount) {
int *result = malloc(acount + bcount);
int aindex,bindex,rindex;
aindex = bindex = rindex = 0;
while (aindex < acount | bindex < bcount) {
int value,avalue = INT_MAX,bvalue = INT_MAX;
if (aindex < acount) { avalue = a[aindex]; }
if (bindex < bcount) { bvalue = b[bindex]; }
// get value from a point.
if (avalue <= bvalue) {
value = avalue;
aindex ++;
}else {
// get value from b point.
value = bvalue;
bindex ++;
}
result[rindex] = value;
rindex ++;
}
return result;
}
I don't understand why does crash when free the point, any answer will helpfull, thanks.
All of your allocations are too small, and thus you are overflowing your buffers.
The malloc function allocates the requested number of bytes. You need to multiply the number of elements you require by sizeof(int) if your elements are int type. e.g.
int *result = malloc((acount + bcount) * sizeof(int));
Other potential problems I spotted while reading your code are:
Using the bitwise-or operator instead of logical-or:
while (aindex < acount | bindex < bcount)
// ^ should be ||
You never free your temporary buffers, thus your program will blow out memory by leaking like crazy. You must free leftData, rightData, sortedLeftData and sortedRightData in the mergeSort function after you are finished with them.
Note that merge sort actually does not require so much allocation. Doing so will have a huge impact on performance. An efficient implementation only requires a single additional buffer for scratch operations, which can be allocated at the beginning.
I did implementation merge sort use single buffer, as the following code:
void mergeSort(int *a, int count) {
int *tempBuffer = malloc(count * sizeof(int));
mergeSortWithBuffer(a, 0, 0, count - 1,tempBuffer);
free(tempBuffer);
}
void mergeSortWithBuffer(int *a, int leftStart, int rightStart, int end, int *tempBuffer) {
int leftCount = rightStart - leftStart;
int rightCount = end - rightStart + 1;
if (leftCount + rightCount <= 1) { return; }
if (leftCount != 0) {
// left dichotomy
int lls = leftStart;
int lrs = leftStart + leftCount/2;
int lnd = rightStart - 1;
mergeSortWithBuffer(a, lls, lrs, lnd,tempBuffer);
}
if (rightCount != 0) {
// right dichotomy
int rls = rightStart;
int rrs = rightStart + rightCount/2;
int rnd = end;
mergeSortWithBuffer(a, rls, rrs, rnd,tempBuffer);
}
mergeData(a, leftStart, rightStart, end, tempBuffer);
}
void mergeData(int *a, int leftStart, int rightStart, int end,int *tempBuffer) {
int leftCount = rightStart - leftStart;
int rightCount = end - rightStart + 1;
int lindex,rindex;
lindex = rindex = 0;
while (lindex < leftCount || rindex < rightCount) {
int lv = INT_MAX,rv = INT_MAX;
if (lindex < leftCount) { lv = a[leftStart + lindex]; }
if (rindex < rightCount) { rv = a[rightStart + rindex]; }
if (lv <= rv) {
tempBuffer[leftStart + lindex + rindex] = lv;
lindex ++;
}else {
tempBuffer[leftStart + lindex + rindex] = rv;
rindex ++;
}
}
for (int index = 0; index < end - leftStart + 1; index ++) {
a[leftStart + index] = tempBuffer[leftStart + index];
}
}
I thought the mergeData function can replace data in the point a each other without the temp buffer, but the logic is too complex and the efficient is not fast, so i add the temp buffer in this function.
Would you have better suggestions if you have willing?
hello guys this is my code :
#include <stdio.h>
#include <stdlib.h>
int power(int a, int b) {
int exponent = b, result = 1;
while (exponent != 0) {
result = result * a;
exponent--;
}
//printf("%d",result);
return result;
}
int fill_it(char ** p, int N, int fliptimes, int column2) {
if (N < 0) return 0;
int counter = 0, l;
char a = 'H';
for (l = 0; l < power(2, fliptimes); l++) {
p[l][column2] = a;
counter++;
if (counter == (power(2, N) / 2)) {
counter = 0;
if (a == 'H') a = 'T';
if (a == 'T') a = 'H';
}
}
fill_it(p, N--, fliptimes, column2++);
}
int main() {
int i, fores, j, l, m;
char ** p;
printf("how many times did you toss the coin?:");
scanf("%d", & fores);
p = (char ** ) malloc((power(2, fores)) * sizeof(char * ));
for (i = 0; i < fores; i++)
p[i] = (char * ) malloc(fores * sizeof(char));
fill_it(p, fores, fores, 0);
for (l = 0; l < power(2, fores); l++) {
for (m = 0; m < fores; m++) {
printf("%c", p[l][m]);
}
}
printf(",");
}
it does compile.But when i run the program it returns a "segmantation fault (core dumped)" error
i know it means that i tried to access memory,i dont have acces to but i dont understand which part of the program is defective
The problem is, you're not allocating enough memory. This line is fine
p = (char ** ) malloc((power(2, fores)) * sizeof(char * ));
but this loop is only allocating memory for part of the 2-dimensional array.
for (i = 0; i < fores; i++)
p[i] = (char * ) malloc(fores * sizeof(char));
The memory allocation should look more like this...
foresSquared = power(2, fores);
p = malloc(foresSquared*sizeof(char *));
for (i = 0; i < foresSquared; i++)
p[i] = malloc(fores);
Since the result of power is going to be consistent, it makes sense to store the value in a variable and use that rather than recalculating it. It'll make the code clearer too.
You also don't need to cast the return value of malloc as C handles that for you. And sizeof(char) isn't needed as it's guaranteed to always be 1.
Im getting the error "invalid operands to binary + (have int* and int*)" and i don't know why It is throwing me this error. how would I go about adding the array elements of the 2 arrays. note both arrays are the same size.
int* complement2_add(int* first_complement2[], int* second_compelment[], int size){
int count = 0,remainder = 0, carryover = 0;
int* cAdd = (int*)malloc(size*sizeof(int));
for(count = size-1; count >= 0; count--){
remainder = first_complement2[count] + second_compelment[count] + carryover;
if(remainder == 1){
cAdd[count] = 1;
carryover = 0;
}
else if(remainder == 2){
cAdd[count] = 0;
carryover = 1;
}
else if(remainder == 3){
cAdd[count] = 1;
carryover = 1;
}
else if(remainder == 0){
cAdd[count] =0;
carryover = 0;
}
}
if(carryover == 1){
cAdd[count] = 1;
}
return cAdd;
}
Then I am calling the function in main like this.
int* add1 = complement_2_add(complement2Array1, complement2Array2, j);
Complement2Array1 and Complement2Array2 are defined the same.
int* complement2Array1 = signed2complement2(signedIntArray1, j);
and signed2complement2 is defined as.
int* signed2complement2(int signed_binary[], int size){
int i = 0;
int* complemt2Array = (int*)malloc(size*sizeof(int));
int flipflag = 0;
for(i = size-1; i>=0;i-- ){
if(flipflag == 0){
complemt2Array[i] = signed_binary[i];
if(signed_binary[i] == 1){
flipflag = 1;
}
}
else{
complemt2Array[i] = signed_binary[i] == 0?1:0;
}
}
return complemt2Array;
}
remainder = first_complement2[count] + second_compelment[count] + carryover;
In this first_complement2[count] , second_compelment[count] both are integer pointers .
As both first_complement and second_complement are array of integer pointers.
You need to dereference them before adding -
remainder = (*first_complement2[count]) + (*second_compelment[count]) + carryover;
EDIT
Didn't you got any warning or error for passing a int * to a function which expects array of integer pointer or int ** ?
int* complement2Array1 = signed2complement2(signedIntArray1, j); // it is an int *
complement2Array1 and complement2array2 has to be of type int ** or to be array of int pointers.
Or simple as #alk Sir suggested use int * instead of int **.
This
int* complement2_add(int* first_complement2[], int* second_compelment[], int size){
if equal to
int* complement2_add(int ** first_complement2, int ** second_compelment, int size){
which from the way you use first_complement2 and second_compelment and the way you call complement2_add() is wrong.
It seems you wanted
int* complement2_add(int * first_complement2, int * second_compelment, int size){
Also add the prototype to it before it is used:
int* complement2_add(int * first_complement2, int * second_compelment, int size);
... somefunc(...)
{
...
int* add1 = complement_2_add(complement2Array1, complement2Array2, j);
...
}
int* complement2_add(int* first_complement2, int* second_compelment, int size)
{
int count = 0,remainder = 0, carryover = 0;
...
I am writing a C programme in which there will be several arrays which lengths are configured in a data file.
I am trying to read I and J from OFDMA.dat, and create arrays Noise, Bw .etc
The lines I have commented belong to the original programme which works:
//#define I 3;
//#define J 2;
//#define NUMROWS (1+I+2*I*J)
//#define NUMCOLS 3*I*J
//#define NUMNZ 6*I*J
Then I tried to read from OFDMA.dat with following code:
while (fgets(buffer, 80, dat) != NULL) {
if (buffer[0] == '#') continue;
if (counter == 1){
maxIter = atoi(buffer);
printf("maxIter \n");
}
if (counter == 2){
Pwr = atof(buffer);
printf("Pwr \n");
}
if (counter == 3){
I = atoi(buffer);
printf("I \n");
Bw = (double*)malloc(sizeof(double)*I);
Noise = (double*)malloc(sizeof(double)*I);
}
if (counter == 4){
J = atoi(buffer);
printf("J \n");
}
if (counter>4 && counter <= 4 + I){
Noise[counter - 5] = atof(buffer);
printf("Noise[%d]: %lf\n", counter - 5, Noise[counter - 5]);
}
if (counter>4 + I&&counter<4 + 2 * I){
Bw[counter - 5 - I] = atof(buffer);
printf("Bw[%d]: %lf\n", counter - I - 5, Bw[counter - I - 5]);
}
counter++;
}
Then visual studio says:
1>OFDMA.c(96): error C2057: expected constant expression
1>OFDMA.c(96): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(102): error C2057: expected constant expression
1>OFDMA.c(102): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(135): error C2057: expected constant expression
1>OFDMA.c(135): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(135): error C2133: 'x' : unknown size
1>OFDMA.c(136): error C2057: expected constant expression
1>OFDMA.c(136): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(136): error C2133: 'slack' : unknown size
1>OFDMA.c(352): error C2057: expected constant expression
1>OFDMA.c(352): error C2466: cannot allocate an array of constant size 0
1>OFDMA.c(546): error C2057: expected constant expression
1>OFDMA.c(546): error C2466: cannot allocate an array of constant size 0
In those lines, I and J are used in declaring arrays. For example:
static int
setproblemdata(char **probname_p, int *numcols_p, int *numrows_p, int *objsen_p,
double **obj_p, double **rhs_p, char **sense_p, int **matbeg_p,
int **matcnt_p, int **matind_p, double **matval_p, double **lb_p,
double **ub_p, char **ctype_p, double Noise_p[I]);
The full codes:
/* Bring in the CPLEX function declarations and the C library
header file stdio.h with the include of cplex.h. */
#include <ilcplex/cplex.h>
/* Bring in the declarations for the string functions */
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <string.h>
/* The problem we are optimizing will have I channels, J users.
* So there will be 1+I+2*I*J rows, 3*I*J columns, and 5*I*J nonzeros. */
//#define I 3;
//#define J 2;
//#define NUMROWS (1+I+2*I*J)
//#define NUMCOLS 3*I*J
//#define NUMNZ 6*I*J
int I, J;
int maxIter;
double Pwr;
double* Bw;
double* Noise;
/* Include declaration for function at end of program */
static int readdata(){
int counter = 1;
FILE * dat;
dat = fopen("OFDMA.dat", "r");
char buffer[80];
if (!dat) // equivalent to saying if ( in_file == NULL )
{
printf("oops, file can't be read\n");
return 1;
}
while (fgets(buffer, 80, dat) != NULL) {
if (buffer[0] == '#') continue;
if (counter == 1){
maxIter = atoi(buffer);
printf("maxIter \n");
}
if (counter == 2){
Pwr = atof(buffer);
printf("Pwr \n");
}
if (counter == 3){
I = atoi(buffer);
printf("I \n");
Bw = (double*)malloc(sizeof(double)*I);
Noise = (double*)malloc(sizeof(double)*I);
NUMROWS=1+I+2*I*J;
NUMCOLS=4*I*J;
NUMNZ=6*I*J;
}
if (counter == 4){
J = atoi(buffer);
printf("J \n");
}
if (counter>4 && counter <= 4 + I){
Noise[counter - 5] = atof(buffer);
printf("Noise[%d]: %lf\n", counter - 5, Noise[counter - 5]);
}
if (counter>4 + I&&counter<4 + 2 * I){
Bw[counter - 5 - I] = atof(buffer);
printf("Bw[%d]: %lf\n", counter - I - 5, Bw[counter - I - 5]);
}
counter++;
}
fclose(dat);
return 0;
}
static int
setproblemdata(char **probname_p, int *numcols_p, int *numrows_p, int *objsen_p,
double **obj_p, double **rhs_p, char **sense_p, int **matbeg_p,
int **matcnt_p, int **matind_p, double **matval_p, double **lb_p,
double **ub_p, char **ctype_p, double Noise_p[I]);
static void
free_and_null(char **ptr);
static int
addcuts(double **matval_p, double **rhs_p, double pbar_p[I*J], const double Bw_[I], double Noise_p[I]);
int main(void) {
/* Declare pointers for the variables and arrays that will contain
the data which define the LP problem. The setproblemdata() routine
allocates space for the problem data. */
char *probname = NULL;
int numcols;
int numrows;
int objsen;
double *obj = NULL;
double *rhs = NULL;
char *sense = NULL;
int *matbeg = NULL;
int *matcnt = NULL;
int *matind = NULL;
double *matval = NULL;
double *lb = NULL;
double *ub = NULL;
char *ctype = NULL;
double *pbar = NULL;
/* Declare and allocate space for the variables and arrays where we will
store the optimization results including the status, objective value,
variable values, and row slacks. */
int solstat;
double objval;
double x[NUMCOLS];
double slack[NUMROWS];
CPXENVptr env = NULL;
CPXLPptr lp = NULL;
int status;
int i, j;
int counter;
int cur_numrows, cur_numcols;
/* Import Data from file OFDMA.dat*/
status = readdata();
if (status){
fprintf(stderr, "Failure to read data from file. \n");
goto TERMINATE;
}
/* Initialize the CPLEX environment */
env = CPXopenCPLEX(&status);
/* If an error occurs, the status value indicates the reason for
failure. A call to CPXgeterrorstring will produce the text of
the error message. Note that CPXopenCPLEX produces no output,
so the only way to see the cause of the error is to use
CPXgeterrorstring. For other CPLEX routines, the errors will
be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */
if (env == NULL) {
char errmsg[CPXMESSAGEBUFSIZE];
fprintf(stderr, "Could not open CPLEX environment.\n");
CPXgeterrorstring(env, status, errmsg);
fprintf(stderr, "%s", errmsg);
goto TERMINATE;
}
/* Turn on output to the screen */
status = CPXsetintparam(env, CPXPARAM_ScreenOutput, CPX_ON);
if (status) {
fprintf(stderr, "Failure to turn on screen indicator, error %d.\n",
status);
goto TERMINATE;
}
/* Fill in the data for the problem. */
status = setproblemdata(&probname, &numcols, &numrows, &objsen, &obj, &rhs,
&sense, &matbeg, &matcnt, &matind, &matval, &lb, &ub, &ctype, Noise);
if (status) {
fprintf(stderr, "Failed to build problem data arrays.\n");
goto TERMINATE;
}
/* Create the problem. */
lp = CPXcreateprob(env, &status, probname);
/* A returned pointer of NULL may mean that not enough memory
was available or there was some other problem. In the case of
failure, an error message will have been written to the error
channel from inside CPLEX. In this example, the setting of
the parameter CPXPARAM_ScreenOutput causes the error message to
appear on stdout. */
if (lp == NULL) {
fprintf(stderr, "Failed to create LP.\n");
goto TERMINATE;
}
/* Main Loop */
for (i = 0; i < maxIter; i++) {
/* Now copy the problem data into the lp */
status = CPXcopylp(env, lp, numcols, numrows, objsen, obj, rhs, sense,
matbeg, matcnt, matind, matval, lb, ub, NULL);
if (status) {
fprintf(stderr, "Failed to copy problem data.\n");
goto TERMINATE;
}
/* Now copy the ctype array */
status = CPXcopyctype(env, lp, ctype);
if (status) {
fprintf(stderr, "Failed to copy ctype\n");
goto TERMINATE;
}
/* Optimize the problem and obtain solution. */
status = CPXmipopt(env, lp);
if (status) {
fprintf(stderr, "Failed to optimize MIP.\n");
goto TERMINATE;
}
solstat = CPXgetstat(env, lp);
/* Write the output to the screen. */
printf("\nSolution status = %d\n", solstat);
status = CPXgetobjval(env, lp, &objval);
if (status) {
fprintf(stderr, "No MIP objective value available. Exiting...\n");
goto TERMINATE;
}
cur_numcols = CPXgetnumcols(env, lp);
status = CPXgetx(env, lp, x, 0, cur_numcols - 1);
if (status) {
fprintf(stderr, "Failed to get optimal integer x.\n");
goto TERMINATE;
}
printf("Solution value = %f\n\n", objval);
/* Add Cuts to the problem */
addcuts(&matval, &rhs, x, Bw, Noise);
}
/* The size of the problem should be obtained by asking CPLEX what
the actual size is, rather than using what was passed to CPXcopylp.
cur_numrows and cur_numcols store the current number of rows and
columns, respectively. */
cur_numrows = CPXgetnumrows(env, lp);
cur_numcols = CPXgetnumcols(env, lp);
status = CPXgetx(env, lp, x, 0, cur_numcols - 1);
if (status) {
fprintf(stderr, "Failed to get optimal integer x.\n");
goto TERMINATE;
}
status = CPXgetslack(env, lp, slack, 0, cur_numrows - 1);
if (status) {
fprintf(stderr, "Failed to get optimal slack values.\n");
goto TERMINATE;
}
for (i = 0; i < cur_numrows; i++) {
printf("Row %d: Slack = %10f\n", i, slack[i]);
}
for (j = 0; j < cur_numcols; j++) {
printf("Column %d: Value = %10f\n", j, x[j]);
}
/* Finally, write a copy of the problem to a file. */
status = CPXwriteprob(env, lp, "OFMDA.lp", NULL);
if (status) {
fprintf(stderr, "Failed to write LP to disk.\n");
goto TERMINATE;
}
TERMINATE:
/* Free up the problem as allocated by CPXcreateprob, if necessary */
if (lp != NULL) {
status = CPXfreeprob(env, &lp);
if (status) {
fprintf(stderr, "CPXfreeprob failed, error code %d.\n", status);
}
}
/* Free up the CPLEX environment, if necessary */
if (env != NULL) {
status = CPXcloseCPLEX(&env);
/* Note that CPXcloseCPLEX produces no output,
so the only way to see the cause of the error is to use
CPXgeterrorstring. For other CPLEX routines, the errors will
be seen if the CPXPARAM_ScreenOutput indicator is set to CPX_ON. */
if (status) {
char errmsg[CPXMESSAGEBUFSIZE];
fprintf(stderr, "Could not close CPLEX environment.\n");
CPXgeterrorstring(env, status, errmsg);
fprintf(stderr, "%s", errmsg);
}
}
/* Free up the problem data arrays, if necessary. */
free_and_null((char **)&probname);
free_and_null((char **)&obj);
free_and_null((char **)&rhs);
free_and_null((char **)&sense);
free_and_null((char **)&matbeg);
free_and_null((char **)&matcnt);
free_and_null((char **)&matind);
free_and_null((char **)&matval);
free_and_null((char **)&lb);
free_and_null((char **)&ub);
free_and_null((char **)&ctype);
return (status);
} /* END main */
static int setproblemdata(char **probname_p, int *numcols_p, int *numrows_p,
int *objsen_p, double **obj_p, double **rhs_p, char **sense_p,
int **matbeg_p, int **matcnt_p, int **matind_p, double **matval_p,
double **lb_p, double **ub_p, char **ctype_p, double Noise_p[I]) {
char *zprobname = NULL; /* Problem name <= 16 characters */
double *zobj = NULL;
double *zrhs = NULL;
char *zsense = NULL;
int *zmatbeg = NULL;
int *zmatcnt = NULL;
int *zmatind = NULL;
double *zmatval = NULL;
double *zlb = NULL;
double *zub = NULL;
char *zctype = NULL;
int status = 0;
int i, j; //channel and user
int counter = 0; //counter
zprobname = (char *)malloc(16 * sizeof (char));
zobj = (double *)malloc(NUMCOLS * sizeof (double));
zrhs = (double *)malloc(NUMROWS * sizeof (double));
zsense = (char *)malloc(NUMROWS * sizeof (char));
zmatbeg = (int *)malloc(NUMCOLS * sizeof (int));
zmatcnt = (int *)malloc(NUMCOLS * sizeof (int));
zmatind = (int *)malloc(NUMNZ * sizeof (int));
zmatval = (double *)malloc(NUMNZ * sizeof (double));
zlb = (double *)malloc(NUMCOLS * sizeof (double));
zub = (double *)malloc(NUMCOLS * sizeof (double));
zctype = (char *)malloc(NUMCOLS * sizeof (char));
if (zprobname == NULL || zobj == NULL || zrhs == NULL || zsense == NULL
|| zmatbeg == NULL || zmatcnt == NULL || zmatind == NULL
|| zmatval == NULL || zlb == NULL || zub == NULL || zctype == NULL) {
status = 1;
goto TERMINATE;
}
strcpy(zprobname, "example");
/* The code is formatted to make a visual correspondence
between the mathematical linear program and the specific data
items. */
/* Objective Function*/
/* coefficients of p_ij and x_ij*/
for (i = 0; i < 2 * I * J; i++) {
zobj[i] = 0;
}
/* coefficients of e_ij*/
for (i = 2 * I * J; i < 3 * I * J; i++) {
zobj[i] = 1;
}
/* Constraints */
/*
* Non-zeros
*
* Every p_ij appears twice, at the 0th and (I+i)th constraints.
* Every x_ij appears twice, at the ...........
* Every e_ij appears once, at the (1+I+I*J+i)th constraint.
*/
for (i = 0; i < I * J; i++) {
zmatbeg[i] = 3 * i;
zmatcnt[i] = 3;
}
for (i = 0; i < I * J; i++) {
zmatbeg[I * J + i] = 3 * I * J + 2 * i;
zmatcnt[I * J + i] = 2;
}
for (i = 0; i < I * J; i++) {
zmatbeg[2 * I * J + i] = 5 * I * J + i;
zmatcnt[2 * I * J + i] = 1;
}
/*
* p_ij appears at the 0th and (I+i+1)th constraints, coefficient is 1.
*/
for (i = 0; i < I * J; i++) {
zmatind[3 * i] = 0;
zmatval[3 * i] = 1.0;
zmatind[3 * i + 1] = I + i + 1;
zmatval[3 * i + 1] = 1.0;
zmatind[3 * i + 2] = 1 + I + I * J + i;
zmatval[3 * i + 2] = -1.0;
}
/*
* x_ij
*/
int ztmpind = I + 1;
for (i = 0; i < 2 * I * J; i += 2) {
zmatind[3 * I * J + i] = i / (2 * J) + 1;
zmatval[3 * I * J + i] = 1;
zmatind[3 * I * J + i + 1] = ztmpind;
zmatval[3 * I * J + i + 1] = -1 * Pwr;
ztmpind++;
}
/*
* e_ij appears at the (1+I+I*J+i)th constraint.
*/
for (i = 0; i < I * J; i++) {
zmatind[5 * I * J + i] = 1 + I + I * J + i;
zmatval[5 * I * J + i] = 1;
}
/*
* Domain of variables
*/
for (i = 0; i < I * J; i++) {
zlb[i] = 0.0;
zub[i] = CPX_INFBOUND;
zctype[i] = 'C';
}
for (i = I * J; i < 2 * I * J; i++) {
zlb[i] = 0.0;
zub[i] = 1.0;
zctype[i] = 'I';
}
for (i = 2 * I * J; i < 3 * I * J; i++) {
zlb[i] = 0.0;
zub[i] = CPX_INFBOUND;
zctype[i] = 'C';
}
/* The right-hand-side values don't fit nicely on a line above. So put
them here. */
zsense[0] = 'L';
zrhs[0] = Pwr;
for (i = 0; i < I; i++) {
zsense[i + 1] = 'L';
zrhs[i + 1] = 1;
}
for (i = 0; i < I * J; i++) {
zsense[I + i + 1] = 'L';
zrhs[I + 1 + i] = 0;
}
counter = 0;
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
zsense[1 + I + I * J + counter] = 'L';
zrhs[1 + I + I * J + counter] = log(1 + Pwr / Noise_p[i]);
counter++;
}
}
TERMINATE:
if (status) {
free_and_null((char **)&zprobname);
free_and_null((char **)&zobj);
free_and_null((char **)&zrhs);
free_and_null((char **)&zsense);
free_and_null((char **)&zmatbeg);
free_and_null((char **)&zmatcnt);
free_and_null((char **)&zmatind);
free_and_null((char **)&zmatval);
free_and_null((char **)&zlb);
free_and_null((char **)&zub);
free_and_null((char **)&zctype);
}
else {
*numcols_p = NUMCOLS;
*numrows_p = NUMROWS;
*objsen_p = CPX_MAX; /* The problem is maximization */
*probname_p = zprobname;
*obj_p = zobj;
*rhs_p = zrhs;
*sense_p = zsense;
*matbeg_p = zmatbeg;
*matcnt_p = zmatcnt;
*matind_p = zmatind;
*matval_p = zmatval;
*lb_p = zlb;
*ub_p = zub;
*ctype_p = zctype;
}
return (status);
} /* END setproblemdata */
/* Add Cuts to the problem */
static int addcuts(double **matval_p, double **rhs_p, double pbar_p[I*J], const double Bw_p[I], double Noise_p[I]) {
double *zmatval = NULL;
double *zrhs = NULL;
int status = 0;
int i, j;
int counter;
zrhs = (double *)malloc(NUMROWS * sizeof (double));
zmatval = (double *)malloc(NUMNZ * sizeof (double));
if (zrhs == NULL || zmatval == NULL) {
status = 1;
goto TERMINATE;
}
zrhs = *rhs_p;
zmatval = *matval_p;
for (i = 0; i < I * J; i++) {
printf("pbar_%d is %f\n", i, pbar_p[i]);
}
/*
*/
counter = 0;
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
printf("e_bar: %f\n", Bw_p[i] * log2(1 + pbar_p[counter] / Noise_p[i]));
}
}
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
printf("xx: %f\n", -Bw_p[i] / (log(2)*(Noise_p[i] + pbar_p[i])));
}
}
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
zmatval[3 * i + 2] = -Bw_p[i] / (log(2)*(Noise_p[i] + pbar_p[i]));
}
}
for (i = 0; i < I; i++) {
for (j = 0; j < J; j++) {
zrhs[1 + I + I * J + i] = Bw_p[i] * log2(1 + pbar_p[i] / Noise_p[i]) - Bw_p[i] / (log(2)*(Noise_p[i] + pbar_p[i])) * pbar_p[i];
}
}
TERMINATE:
if (status) {
free_and_null((char **)&zrhs);
}
else {
*rhs_p = zrhs;
}
return (status);
} /* END addcuts */
/* This simple routine frees up the pointer *ptr, and sets *ptr to NULL */
static void free_and_null(char **ptr) {
if (*ptr != NULL) {
free(*ptr);
*ptr = NULL;
}
} /* END free_and_null */
Can anybody give me an example please?
EDIT 2 (assigning values to #define value)
There are many parts to your code that need to be addressed, however, sticking only to the part you have asked about, consider this section of your code:
Bw = (double*)malloc(sizeof(double)*I);
Noise = (double*)malloc(sizeof(double)*I);
NUMROWS=1+I+2*I*J;
NUMCOLS=4*I*J;
NUMNZ=6*I*J;
It is not the malloc statements that are being addressed by the error messages: example:
1>OFDMA.c(96): error C2057: expected constant expression
1>OFDMA.c(96): error C2466: cannot allocate an array of constant size 0
...
...
rather the lines where you are attempting to assign values to NUMROWS, NUMCOLS etc. As I have said below, these you have created using #define, and are not changeable during run-time.
EDIT (to address I & J) When I try to read I and J from a data file, the visual studio doesn't allow me to do so saying:
expected constant expression
You've created I & J as #defines,
#define I ii
#define J 2
they are therefore not changeable during runtime. If you want them to be changeble, created them as int, char[], or double. example:
char I[10];
int J;
They will then be able to accept assignments during run time.
It is not clear from your question exactly what you are having problems with, reading the initializer value in from a file, or using it to initialize a variable.
This addresses the initialization part only:
C99 allows for variable array initializers, so reading values in from a file, (and converting them from string to int or float) then using them to initialize an array, is completely legal. For example:
float read_and_process(int n)
{
float vals[n];//variable array initializer "n"
for (int i = 0; i < n; i++)
vals[i] = read_val();
return process(vals, n);
}
Reference1
Reference2
You first have to understand that the preprocessor will change every instance of I and J to their respective values of 3 and 2 before the actual compilation kicks in and spits out this error message.
To dynamically allocate an array you need to use malloc. You can find plenty of example by Googling.
In C, arrays length are constant and they are defined in compiling time.
If you want to trade with a variable-length array, you have to use malloc:
double* B;
double* N;
double* NZmatrix;
static int main(){
int I, NZ;
I = 2;
NZ = 3;
B = (double*)malloc(sizeof(double)*I);
N = (double*)malloc(sizeof(double)*I)
NZmatrix = (double*)malloc(sizeof(double)*NZ)
}
And I and NZ are integer variables that contain the desired length.